Symmetrix clones

Introduction

_images/symclone.png

EMC Symmetrix arrays clones allow multi-target block device replication, splitting a set of cloned devices, resyncing and merging changes on a clone set to its source set. After the initial full copy, all resyncs are delta-based. These excellent features allow opensvc to drive services using a cloned device set, handling the splitting on start-up and providing a simple command for resync and merge-back. This kind of services are often used for maintenance, pre-production, performance testing environments, where the source device set is used for production. The following documentation presents the configuration of such a service.

A service with only symclone sync resource can be defined to drive the clone of other servers, just for the benefit of centralized logging and scheduling.

Command set

sync break
Activate the resource devices, breaking the data-replication. The source starts to log differences. The devices are promoted to read-write access.
sync resync
Re-establish the resource devices replication. This command verifies the service is down before proceeding.
sync update
Re-establish the resource devices replication. This command verifies the service is down before proceeding.

Status

up
The last replication occured less than 'sync_max_delay' minutes ago.
warn
The last replication occured more than 'sync_max_delay' minutes ago.
down
Device are in a unexpected state or not present in the resource symmetrix disk group.

Service configuration

Pre-requisites

The symcli commands must be installed in the standard location on the nodes running this service resource type.

Service configuration file

##############################################################################
#                                                                            #
# sync, type symclone                                                        #
#                                                                            #
##############################################################################

[sync#0]
;type = symclone

#
# keyword:       consistent
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      True
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  Use -consistent in symclone commands.
#
;consistent = True

#
# keyword:       symid
# ----------------------------------------------------------------------------
#  required:     True
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     False
#
#  desc:  Identifier of the symmetrix array hosting the source and target
#         devices pairs pointed by 'pairs'.
#
;symid = foo

#
# keyword:       pairs
# ----------------------------------------------------------------------------
#  required:     True
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  Whitespace-separated list of devices <src>:<dst> devid pairs to
#         drive with this resource.
#
;pairs = 00B60:00B61 00B62:00B63

#
# keyword:       precopy
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      True
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  Use -precopy on recreate.
#
;precopy = True

#
# keyword:       restart
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      0
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  The agent will try to restart a resource n times before falling back
#         to the monitor action.
#
;restart = 0

#
# keyword:       tags
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A list of tags. Arbitrary tags can be used to limit action scope to
#         resources with a specific tag. Some tags can influence the driver
#         behaviour. For example the 'encap' tag assigns the resource to the
#         encapsulated service, 'noaction' avoids any state changing action
#         from the driver, 'nostatus' forces the status to n/a.
#
;tags = foo

#
# keyword:       subset
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  Assign the resource to a specific subset.
#
;subset = foo

#
# keyword:       monitor
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      False
#  candidates:   True | False
#  depends:      None
#  scopable:     True
#
#  desc:  A monitored resource will trigger a node suicide if the service has
#         a heartbeat resource in up state
#
;monitor = False

#
# keyword:       disable
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      False
#  candidates:   True | False
#  depends:      None
#  scopable:     True
#
#  desc:  A disabled resource will be ignored on service startup and shutdown.
#
;disable = False

#
# keyword:       optional
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      False
#  candidates:   True | False
#  depends:      None
#  scopable:     True
#
#  desc:  Possible values are 'true' or 'false'. Actions on resource will be
#         tried upon service startup and shutdown, but action failures will be
#         logged and passed over. Useful for resources like dump filesystems
#         for example.
#
;optional = False

#
# keyword:       always_on
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   nodes | drpnodes | nodes drpnodes
#  depends:      None
#  scopable:     False
#
#  desc:  Possible values are 'nodes', 'drpnodes' or 'nodes drpnodes', or a
#         list of nodes. Sets the nodes on which the resource is always kept
#         up. Primary usage is file synchronization receiving on non-shared
#         disks. Don't set this on shared disk !! danger !!
#
;always_on = nodes

#
# keyword:       pre_unprovision
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute before the resource unprovision
#         action. Errors do not interrupt the action.
#
;pre_unprovision = foo

#
# keyword:       post_unprovision
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute after the resource unprovision
#         action. Errors do not interrupt the action.
#
;post_unprovision = foo

#
# keyword:       pre_provision
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute before the resource provision action.
#         Errors do not interrupt the action.
#
;pre_provision = foo

#
# keyword:       post_provision
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute after the resource provision action.
#         Errors do not interrupt the action.
#
;post_provision = foo

#
# keyword:       pre_start
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute before the resource start action.
#         Errors do not interrupt the action.
#
;pre_start = foo

#
# keyword:       post_start
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute after the resource start action.
#         Errors do not interrupt the action.
#
;post_start = foo

#
# keyword:       pre_stop
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute before the resource stop action.
#         Errors do not interrupt the action.
#
;pre_stop = foo

#
# keyword:       post_stop
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute after the resource stop action.
#         Errors do not interrupt the action.
#
;post_stop = foo

#
# keyword:       pre_sync_nodes
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute before the resource sync_nodes
#         action. Errors do not interrupt the action.
#
;pre_sync_nodes = foo

#
# keyword:       post_sync_nodes
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute after the resource sync_nodes action.
#         Errors do not interrupt the action.
#
;post_sync_nodes = foo

#
# keyword:       pre_sync_drp
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute before the resource sync_drp action.
#         Errors do not interrupt the action.
#
;pre_sync_drp = foo

#
# keyword:       post_sync_drp
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute after the resource sync_drp action.
#         Errors do not interrupt the action.
#
;post_sync_drp = foo

#
# keyword:       pre_sync_resync
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute before the resource sync_resync
#         action. Errors do not interrupt the action.
#
;pre_sync_resync = foo

#
# keyword:       post_sync_resync
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute after the resource sync_resync
#         action. Errors do not interrupt the action.
#
;post_sync_resync = foo

#
# keyword:       pre_sync_update
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute before the resource sync_update
#         action. Errors do not interrupt the action.
#
;pre_sync_update = foo

#
# keyword:       post_sync_update
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute after the resource sync_update
#         action. Errors do not interrupt the action.
#
;post_sync_update = foo

#
# keyword:       blocking_pre_unprovision
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute before the resource unprovision
#         action. Errors interrupt the action.
#
;blocking_pre_unprovision = foo

#
# keyword:       blocking_post_unprovision
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute after the resource unprovision
#         action. Errors interrupt the action.
#
;blocking_post_unprovision = foo

#
# keyword:       blocking_pre_provision
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute before the resource provision action.
#         Errors interrupt the action.
#
;blocking_pre_provision = foo

#
# keyword:       blocking_post_provision
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute after the resource provision action.
#         Errors interrupt the action.
#
;blocking_post_provision = foo

#
# keyword:       blocking_pre_start
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute before the resource start action.
#         Errors interrupt the action.
#
;blocking_pre_start = foo

#
# keyword:       blocking_post_start
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute after the resource start action.
#         Errors interrupt the action.
#
;blocking_post_start = foo

#
# keyword:       blocking_pre_stop
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute before the resource stop action.
#         Errors interrupt the action.
#
;blocking_pre_stop = foo

#
# keyword:       blocking_post_stop
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute after the resource stop action.
#         Errors interrupt the action.
#
;blocking_post_stop = foo

#
# keyword:       blocking_pre_sync_nodes
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute before the resource sync_nodes
#         action. Errors interrupt the action.
#
;blocking_pre_sync_nodes = foo

#
# keyword:       blocking_post_sync_nodes
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute after the resource sync_nodes action.
#         Errors interrupt the action.
#
;blocking_post_sync_nodes = foo

#
# keyword:       blocking_pre_sync_drp
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute before the resource sync_drp action.
#         Errors interrupt the action.
#
;blocking_pre_sync_drp = foo

#
# keyword:       blocking_post_sync_drp
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute after the resource sync_drp action.
#         Errors interrupt the action.
#
;blocking_post_sync_drp = foo

#
# keyword:       blocking_pre_sync_resync
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute before the resource sync_resync
#         action. Errors interrupt the action.
#
;blocking_pre_sync_resync = foo

#
# keyword:       blocking_post_sync_resync
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute after the resource sync_resync
#         action. Errors interrupt the action.
#
;blocking_post_sync_resync = foo

#
# keyword:       blocking_pre_sync_update
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute before the resource sync_update
#         action. Errors interrupt the action.
#
;blocking_pre_sync_update = foo

#
# keyword:       blocking_post_sync_update
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A command or script to execute after the resource sync_update
#         action. Errors interrupt the action.
#
;blocking_post_sync_update = foo

#
# keyword:       unprovision_depends
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A whitespace-separated list of conditions to meet to accept running
#         a 'unprovision' action. A condition is expressed as
#         <rid>(<state>,...). If states are ommited, 'up,stdby up' is used as
#         the default expected states.
#
;unprovision_depends =

#
# keyword:       provision_depends
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A whitespace-separated list of conditions to meet to accept running
#         a 'provision' action. A condition is expressed as
#         <rid>(<state>,...). If states are ommited, 'up,stdby up' is used as
#         the default expected states.
#
;provision_depends =

#
# keyword:       start_depends
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A whitespace-separated list of conditions to meet to accept running
#         a 'start' action. A condition is expressed as <rid>(<state>,...). If
#         states are ommited, 'up,stdby up' is used as the default expected
#         states.
#
;start_depends =

#
# keyword:       stop_depends
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A whitespace-separated list of conditions to meet to accept running
#         a 'stop' action. A condition is expressed as <rid>(<state>,...). If
#         states are ommited, 'up,stdby up' is used as the default expected
#         states.
#
;stop_depends =

#
# keyword:       sync_nodes_depends
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A whitespace-separated list of conditions to meet to accept running
#         a 'sync_nodes' action. A condition is expressed as
#         <rid>(<state>,...). If states are ommited, 'up,stdby up' is used as
#         the default expected states.
#
;sync_nodes_depends =

#
# keyword:       sync_drp_depends
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A whitespace-separated list of conditions to meet to accept running
#         a 'sync_drp' action. A condition is expressed as <rid>(<state>,...).
#         If states are ommited, 'up,stdby up' is used as the default expected
#         states.
#
;sync_drp_depends =

#
# keyword:       sync_update_depends
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A whitespace-separated list of conditions to meet to accept running
#         a 'sync_update' action. A condition is expressed as
#         <rid>(<state>,...). If states are ommited, 'up,stdby up' is used as
#         the default expected states.
#
;sync_update_depends =

#
# keyword:       sync_break_depends
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A whitespace-separated list of conditions to meet to accept running
#         a 'sync_break' action. A condition is expressed as
#         <rid>(<state>,...). If states are ommited, 'up,stdby up' is used as
#         the default expected states.
#
;sync_break_depends =

#
# keyword:       sync_resync_depends
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  A whitespace-separated list of conditions to meet to accept running
#         a 'sync_resync' action. A condition is expressed as
#         <rid>(<state>,...). If states are ommited, 'up,stdby up' is used as
#         the default expected states.
#
;sync_resync_depends =

#
# keyword:       schedule
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      None
#  candidates:   None
#  depends:      None
#  scopable:     True
#
#  desc:  Set the this resource synchronization schedule. See
#         usr/share/doc/node.conf for the schedule syntax reference.
#
;schedule = ["00:00-01:00@61 mon", "02:00-03:00@61 tue-sun"]

#
# keyword:       sync_max_delay
# ----------------------------------------------------------------------------
#  required:     False
#  provisioning: False
#  default:      1440
#  candidates:   None
#  depends:      None
#  scopable:     False
#
#  desc:  Unit is minutes. This sets to delay above which the sync status of
#         the resource is to be considered down. Should be set according to
#         your application service level agreement. The cron job frequency
#         should be set between 'sync_min_delay' and 'sync_max_delay'.
#
;sync_max_delay = 1440

You can setup as many sync resources as needed to ensure a consistent replication scenario. For example, you might want to clone an Oracle database data first, then in a subsequent sync, clone the archivelogs.

Symmetrix clone configuration

Create a symmetrix disk group

# symdg create -type REGULAR DGCVI

Add source devices to the group

# symld -g DGCVI add dev 1234 DEV001

Add target devices to the group

# symld -g DGCVI add dev 4321 CLONE001

Start the initial copy

# symclone -g DGCVI create -diff -precopy DEV001 sym ld CLONE001  # [more pairs...]

Examples

Resync service clones

# svcmgr -s aastmphpux sync resync
* IISTMPHPUX.SYNC#2 - INFO - /usr/symcli/bin/symclone -g DGCVI -noprompt recreate -precopy -i 20 -c 30 DEV001 sym ld CLONE001
* IISTMPHPUX.SYNC#2 - WARNING - command succesful but stderr

'Recreate' operation execution is in progress for device 'DEV001'
paired with target device 'CLONE001' in
device group 'DGCVI'. Please wait...

'Recreate' operation successfully initiated for device 'DEV001'
in group 'DGCVI' paired with target device 'CLONE001'.

Start a service using clones

# svcmgr -s aastmphpux start
* IISTMPHPUX.IP#1 - INFO - ifconfig lan900:1 192.168.32.41 netmask 255.255.252.0 up
* IISTMPHPUX.IP#1 - WARNING - arp annouce skipped. install 'arping'
* IISTMPHPUX.SYNC#2 - INFO - /usr/symcli/bin/symclone -g DGCVI -noprompt activate -i 20 -c 30 DEV001 sym ld CLONE001
* IISTMPHPUX.SYNC#2 - WARNING - command succesful but stderr

'Activate' operation execution is in progress for device 'DEV001'
paired with target device 'CLONE001' in
device group 'DGCVI'. Please wait...

'Activate' operation successfully executed for device 'DEV001'
in group 'DGCVI' paired with target device 'CLONE001'.


* IISTMPHPUX.SYNC#2 - INFO - waiting for copied state (max 300 secs)
* IISTMPHPUX.VG#1 - INFO - vgimport -m /var/lib/opensvc/vg_aastmphpux_vgCVI.map -s -N vgCVI
* IISTMPHPUX.VG#1 - INFO - vgchange -a y vgCVI
* IISTMPHPUX.FS#1 - INFO - fsck -F vxfs -y /dev/vgCVI/lv_CVI
* IISTMPHPUX.FS#1 - INFO - mount -F vxfs /dev/vgCVI/lv_CVI /aaststcvi