<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<!--

 CDDL HEADER START

 The contents of this file are subject to the terms of the
 Common Development and Distribution License, Version 1.0 only
 (the "License").  You may not use this file except in compliance
 with the License.

 You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 or http://www.opensolaris.org/os/licensing.
 See the License for the specific language governing permissions
 and limitations under the License.

 When distributing Covered Code, include this CDDL HEADER in each
 file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 If applicable, add the following below this CDDL HEADER, with the
 fields enclosed by brackets "[]" replaced with your own identifying
 information: Portions Copyright [yyyy] [name of copyright owner]

 CDDL HEADER END

 Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 Use is subject to license terms.

-->

<service_bundle type='manifest' name='TIMFzfssnap:filesystem-zfs-auto-snapshot'>

<service
	name='system/filesystem/zfs/auto-snapshot'
	type='service'
	version='0.11'>

	<!-- we need to be multi-user to ensure the homedirs for the
	zfssnap role is mounted -->
	<dependency
		name='multi-user'
		grouping='require_all'
		restart_on='none'
		type='service'>
		<service_fmri value='svc:/milestone/multi-user' />
	</dependency>
	
	<!-- we also need cron -->
	<dependency
		name="cron"
		grouping="require_all"
		restart_on="none"
		type="service">
		<service_fmri value="svc:/system/cron" />
	</dependency>

	<property_group name='startd' type='framework'>
		<propval name='duration' type='astring' value='transient' />
	</property_group>

        <property_group name='general' type='framework'>
            <propval name='action_authorization' type='astring'
                value='solaris.smf.manage.zfs-auto-snapshot' />
            <propval name='value_authorization' type='astring'
                value='solaris.smf.manage.zfs-auto-snapshot' />
        </property_group>


<!-- the properties we expect that any instance will define
they being :
	fs-name : The name of the filesystem we want to snapshot.

	The special filesystem name "//" indicates we should
	look at the com.sun:auto-snapshot ZFS user
	properties on datasets, set to "true" if the dataset
	should have snapshots taken by this instance.
	
	If set to false or unset, snapshots will not be taken
	by this instance.
	
	The snapshot-children property is ignored when using
	this setting, instead the system will automatically
	determine how to take snapshots, based on which datasets
	have true, false or unset property values.

	Setting com.sun:auto-snapshot:<label> will override 
	the general setting for com.sun:auto-snapshot.
	

	interval : minutes | hours | days | months | none

	For the interval "none" a cron job is not created for that
	instance - instead the user can manually file the method
	script to take snapshots defined by the rest of the properties
	in the instance. The period and offset values are ignored in
	this case.

	period : How many (m,h,d,m) do we wait between snapshots

	offset : The offset into the time period we want

	keep : How many snapshots we should keep, otherwise, we
		delete the oldest when we hit this threshold

        snapshot-children : Whether we should recursively snapshot
		all filesystems contained within. Ignored when
		using the "//" fs-name value.

	backup : If we want to perform a "zfs send" for our backup
		we set this - either to "full" or "incremental".
		If set to "none", we don't perform backups.

        backup-save-cmd : A command string to save the backup - if unset,
		we return an error and move the service to
		maintenance.

	backup-lock : A string we set when a backup operation is in
		progress, to prevent two backups from the same
		service instance running into each other. Not
		completely flawless, but okay. Due to 6338294,
		we use the keyword "unlocked" to indicate that
		the lock is not held.	   

	label : A string that allows us to differentiate this set
		of snapshot schedules from others configured for the
		same filesystem. This is not usually needed and can
		be left unset, but it can be useful in some 
		situations (particularly for backups).

	verbose : Set to false by default, setting to true results
		in the service printing more detail in the log
		about what it's doing.

	avoidscrub : Set to false by default, this determines whether
		we should avoid taking snapshots on any pools that have
		a scrub or resilver in progress.
		More info in the bugid:
		6343667 need itinerary so interrupted scrub/resilver
			doesn't have to start over


	 -->
	<property_group name="zfs" type="application">
	  <propval name="fs-name" type="astring" value="Not set" override="true"/>
	  <propval name="interval" type="astring" value="Not set" override="true"/>
	  <propval name="offset" type="astring" value="Not set" override="true"/>
	  <propval name="snapshot-children" type="boolean" value="false" override="true"/>
	  <propval name="keep" type="astring" value="all" override="true"/>

	  <propval name="backup" type="astring" value="none" override="true"/>
	  <propval name="backup-save-cmd" type="astring" value="" override="true"/>
	  <propval name="backup-lock" type="astring" value="unlocked" override="true"/>

	  <propval name="label" type="astring" value="" override="true"/>
	  <propval name="verbose" type="boolean" value="false" override="true"/>
	  <propval name="avoidscrub" type="boolean" value="false" override="true"/>

	  <propval name='action_authorization' type='astring'
		value='solaris.smf.manage.zfs-auto-snapshot' />
	  <propval name='value_authorization' type='astring'
		value='solaris.smf.manage.zfs-auto-snapshot' />
	</property_group>

	<!-- we're *not* defining an instance here : the idea is that instances
	  of this service will be created, one per set of auto-snapshots we want
	  to take. For reference purposes, here's what such an instance should
	  look like :

	<instance name='tank-timf' enabled='false' >

	   note: recommend an infinite timeout here - or at least a long one,
	         SMF tries to start all instances in parallel, however, since
		 we need to add entries to cron, we need to put locks around
		 start and stop, running these serially - if there are
		 sufficiently high numbers of instances, we can trip, say a 10
		 sec. timeout.

        <exec_method
                type='method'
                name='start'
                exec='/lib/svc/method/zfs-auto-snapshot start'
                timeout_seconds='0'>
                        <method_context>
                                <method_credential user='zfssnap' group='staff' />
                        </method_context>
        </exec_method>

        <exec_method
                type='method'
                name='stop'
                exec='/lib/svc/method/zfs-auto-snapshot stop'
                timeout_seconds='0' >
                        <method_context>
                                <method_credential user='zfssnap' group='staff' />
                        </method_context>
        </exec_method>

        <property_group name='startd' type='framework'>
        	<propval name='duration' type='astring' value='transient' />
        </property_group>

	<property_group name="zfs" type="application">

	  <propval name="fs-name" type="astring" value="tank/timf"/>
	  <propval name="interval" type="astring" value="days"/>
	  <propval name="period" type="astring" value="7"/>
	  <propval name="offset" type="astring" value="0"/>
	  <propval name="snapshot-children" type="boolean" value="false"/>

	  <propval name="backup" type="astring" value="full" override="true"/>
	  <propval name="backup-save-cmd" type="astring" override="true"
			value="ssh haiiro.ireland zfs receive -d tank/data "/>
	  <propval name="backup-lock" type="astring" value="unlocked" 
			override="true"/>

	  <propval name="label" type="astring" value="all" override="true"/>

	  <propval name="verbose" type="boolean" value="false" override="true"/>

	  <propval name="avoidscrub" type="boolean" value="false" override="true"/>

	</property_group>

	</instance>

	A set of instances are provided that snapshot periodically hourly, 
	daily, weekly, monthly, and at 15 minute intervals, and have their
	fs-name set to "//", consulting the com.sun:auto-snapshot:hourly,etc.
	ZFS user properties to determine which datasets to snapshot.

	-->

	<stability value='Unstable' />

	<template>
		<common_name>
			<loctext xml:lang='C'>
ZFS automatic snapshots
			</loctext>
		</common_name>
		<description>
			<loctext xml:lang='C'>
This service provides system support for taking automatic snapshots of ZFS
filesystems.

In order to use this service, you must create a service instance per set of automatic snapshots you want to take.

The on starting a service instance, a cron job corresponding to the properties set in the instance is created on the host. This cron job will regularly take snapshots of the specified ZFS filesystem.

On stopping the service, that cron job is removed.

We also have the ability to perform backups, done using the "zfs send" command.  A property set in the service called "backup-save-cmd" can be configured as the command used to save the backup stream. See the zfs(1M) man page for an example.  The backups can be either "full" backups, or "incremental" backups - for each incremental backup, a full backup must be configured first. If for some reason an incremental backup fails, a full backup is performed instead.

By default, snapshots will not be taken of any datasets resident on pools that are currently being scrubbed or resilvered. This can behaviour can be changed using the zfs/avoid scrub service property.

Care should be taken when configuring backups to ensure that the time granularity of the cron job is sufficient to allow the backup to complete between invocations of each backup. We perform locking to ensure that two backups of the same filesystem cannot run simultaneously, but will move the service into "maintenance" state should this occur.
			</loctext>
		</description>
	</template>
</service>

</service_bundle>
