2008-01-16 12:26:35 +03:00
/*
Unix SMB / CIFS implementation .
Samba VFS module for handling offline files
with Tivoli Storage Manager Space Management
2008-01-18 17:34:21 +03:00
( c ) Alexander Bokovoy , 2007 , 2008
( c ) Andrew Tridgell , 2007 , 2008
2008-01-16 12:26:35 +03:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
/*
This VFS module accepts following options :
2008-01-18 17:34:21 +03:00
tsmsm : hsm script = < path to hsm script > ( default does nothing )
2008-01-16 12:26:35 +03:00
hsm script should point to a shell script which accepts two arguments :
< operation > < filepath >
where < operation > is currently ' offline ' to set offline status of the < filepath >
tsmsm : online ratio = ratio to check reported size against actual file size ( 0.5 by default )
2012-03-22 02:40:44 +04:00
tsmsm : dmapi attribute = name of DMAPI attribute that is present when a file is offline .
2008-01-18 17:34:21 +03:00
Default is " IBMobj " ( which is what GPFS uses )
2008-01-16 12:26:35 +03:00
The TSMSM VFS module tries to avoid calling expensive DMAPI calls with some heuristics
based on the fact that number of blocks reported of a file multiplied by 512 will be
bigger than ' online ratio ' of actual size for online ( non - migrated ) files .
2008-01-18 17:34:21 +03:00
If checks fail , we call DMAPI and ask for specific attribute which present for
2008-01-16 12:26:35 +03:00
offline ( migrated ) files . If this attribute presents , we consider file offline .
*/
# include "includes.h"
2011-03-23 00:34:22 +03:00
# include "smbd/smbd.h"
2012-08-10 13:33:54 +04:00
# include "lib/util/tevent_unix.h"
2008-01-16 12:26:35 +03:00
# ifndef USE_DMAPI
# error "This module requires DMAPI support!"
# endif
# ifdef HAVE_XFS_DMAPI_H
# include <xfs/dmapi.h>
# elif defined(HAVE_SYS_DMI_H)
# include <sys/dmi.h>
# elif defined(HAVE_SYS_JFSDMAPI_H)
# include <sys/jfsdmapi.h>
# elif defined(HAVE_SYS_DMAPI_H)
# include <sys/dmapi.h>
# elif defined(HAVE_DMAPI_H)
# include <dmapi.h>
# endif
# ifndef _ISOC99_SOURCE
# define _ISOC99_SOURCE
# endif
# include <math.h>
/* optimisation tunables - used to avoid the DMAPI slow path */
# define FILE_IS_ONLINE_RATIO 0.5
2008-01-18 17:34:21 +03:00
/* default attribute name to look for */
2008-01-16 12:26:35 +03:00
# define DM_ATTRIB_OBJECT "IBMObj"
struct tsmsm_struct {
float online_ratio ;
char * hsmscript ;
2008-01-18 17:34:21 +03:00
const char * attrib_name ;
2008-04-08 15:17:53 +04:00
const char * attrib_value ;
2008-01-16 12:26:35 +03:00
} ;
static void tsmsm_free_data ( void * * pptr ) {
struct tsmsm_struct * * tsmd = ( struct tsmsm_struct * * ) pptr ;
if ( ! tsmd ) return ;
TALLOC_FREE ( * tsmd ) ;
}
2008-01-18 17:34:21 +03:00
/*
called when a client connects to a share
*/
2008-01-16 12:26:35 +03:00
static int tsmsm_connect ( struct vfs_handle_struct * handle ,
const char * service ,
const char * user ) {
2009-12-01 02:53:04 +03:00
struct tsmsm_struct * tsmd ;
2008-01-16 12:26:35 +03:00
const char * fres ;
2008-01-18 17:34:21 +03:00
const char * tsmname ;
2009-12-01 02:53:04 +03:00
int ret = SMB_VFS_NEXT_CONNECT ( handle , service , user ) ;
if ( ret < 0 ) {
return ret ;
}
2011-06-07 05:44:43 +04:00
tsmd = talloc_zero ( handle , struct tsmsm_struct ) ;
2008-01-16 12:26:35 +03:00
if ( ! tsmd ) {
2009-12-01 02:53:04 +03:00
SMB_VFS_NEXT_DISCONNECT ( handle ) ;
2008-01-16 12:26:35 +03:00
DEBUG ( 0 , ( " tsmsm_connect: out of memory! \n " ) ) ;
return - 1 ;
}
2008-01-18 17:34:21 +03:00
if ( ! dmapi_have_session ( ) ) {
2009-12-01 02:53:04 +03:00
SMB_VFS_NEXT_DISCONNECT ( handle ) ;
2008-01-16 12:26:35 +03:00
DEBUG ( 0 , ( " tsmsm_connect: no DMAPI session for Samba is available! \n " ) ) ;
TALLOC_FREE ( tsmd ) ;
return - 1 ;
}
tsmname = ( handle - > param ? handle - > param : " tsmsm " ) ;
2008-01-18 17:34:21 +03:00
/* Get 'hsm script' and 'dmapi attribute' parameters to tsmd context */
2012-08-08 13:23:12 +04:00
tsmd - > hsmscript = lp_parm_talloc_string (
tsmd , SNUM ( handle - > conn ) , tsmname ,
" hsm script " , NULL ) ;
2008-01-18 17:34:21 +03:00
talloc_steal ( tsmd , tsmd - > hsmscript ) ;
2012-08-08 13:23:12 +04:00
tsmd - > attrib_name = lp_parm_talloc_string (
tsmd , SNUM ( handle - > conn ) , tsmname ,
" dmapi attribute " , DM_ATTRIB_OBJECT ) ;
2008-01-18 17:34:21 +03:00
talloc_steal ( tsmd , tsmd - > attrib_name ) ;
2008-04-08 15:17:53 +04:00
2012-08-08 13:23:12 +04:00
tsmd - > attrib_value = lp_parm_talloc_string (
tsmd , SNUM ( handle - > conn ) , tsmname ,
" dmapi value " , NULL ) ;
2008-04-08 15:17:53 +04:00
talloc_steal ( tsmd , tsmd - > attrib_value ) ;
2008-01-18 17:34:21 +03:00
/* retrieve 'online ratio'. In case of error default to FILE_IS_ONLINE_RATIO */
2008-01-16 12:26:35 +03:00
fres = lp_parm_const_string ( SNUM ( handle - > conn ) , tsmname ,
2008-01-18 17:34:21 +03:00
" online ratio " , NULL ) ;
if ( fres = = NULL ) {
2008-01-16 12:26:35 +03:00
tsmd - > online_ratio = FILE_IS_ONLINE_RATIO ;
2008-01-18 17:34:21 +03:00
} else {
tsmd - > online_ratio = strtof ( fres , NULL ) ;
2008-01-29 18:33:22 +03:00
if ( tsmd - > online_ratio > 1.0 | |
tsmd - > online_ratio < = 0.0 ) {
2008-01-18 17:34:21 +03:00
DEBUG ( 1 , ( " tsmsm_connect: invalid online ration %f - using %f. \n " ,
2008-01-29 18:33:22 +03:00
tsmd - > online_ratio , ( float ) FILE_IS_ONLINE_RATIO ) ) ;
2008-01-18 17:34:21 +03:00
}
2008-01-16 12:26:35 +03:00
}
/* Store the private data. */
SMB_VFS_HANDLE_SET_DATA ( handle , tsmd , tsmsm_free_data ,
struct tsmsm_struct , return - 1 ) ;
2009-12-01 02:53:04 +03:00
return 0 ;
2008-01-16 12:26:35 +03:00
}
2008-01-17 14:57:35 +03:00
static bool tsmsm_is_offline ( struct vfs_handle_struct * handle ,
2011-02-25 16:37:34 +03:00
const struct smb_filename * fname ,
SMB_STRUCT_STAT * stbuf )
{
2008-01-16 12:26:35 +03:00
struct tsmsm_struct * tsmd = ( struct tsmsm_struct * ) handle - > data ;
2008-01-18 17:34:21 +03:00
const dm_sessid_t * dmsession_id ;
2008-01-16 12:26:35 +03:00
void * dmhandle = NULL ;
size_t dmhandle_len = 0 ;
size_t rlen ;
dm_attrname_t dmname ;
2008-01-29 17:43:49 +03:00
int ret , lerrno ;
2008-01-17 14:57:35 +03:00
bool offline ;
2008-12-01 08:20:22 +03:00
char * buf = NULL ;
2008-04-08 18:43:30 +04:00
size_t buflen ;
2011-02-25 16:37:34 +03:00
NTSTATUS status ;
char * path ;
status = get_full_smb_filename ( talloc_tos ( ) , fname , & path ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return false ;
}
2008-01-16 12:26:35 +03:00
/* if the file has more than FILE_IS_ONLINE_RATIO of blocks available,
then assume it is not offline ( it may not be 100 % , as it could be sparse ) */
2010-11-17 19:52:06 +03:00
if ( 512 * stbuf - > st_ex_blocks > =
2009-05-14 17:34:42 +04:00
stbuf - > st_ex_size * tsmd - > online_ratio ) {
2010-11-17 19:45:01 +03:00
DEBUG ( 10 , ( " %s not offline: st_blocks=%llu st_size=%llu "
2009-05-14 17:34:42 +04:00
" online_ratio=%.2f \n " , path ,
2010-11-17 19:45:01 +03:00
( unsigned long long ) stbuf - > st_ex_blocks ,
( unsigned long long ) stbuf - > st_ex_size , tsmd - > online_ratio ) ) ;
2008-01-17 14:57:35 +03:00
return false ;
2008-01-16 12:26:35 +03:00
}
2008-01-18 17:34:21 +03:00
dmsession_id = dmapi_get_current_session ( ) ;
if ( dmsession_id = = NULL ) {
DEBUG ( 2 , ( " tsmsm_is_offline: no DMAPI session available? "
" Assume file is online. \n " ) ) ;
return false ;
}
2008-01-16 12:26:35 +03:00
/* using POSIX capabilities does not work here. It's a slow path, so
* become_root ( ) is just as good anyway ( tridge )
*/
/* Also, AIX has DMAPI but no POSIX capablities support. In this case,
* we need to be root to do DMAPI manipulations .
*/
become_root ( ) ;
/* go the slow DMAPI route */
if ( dm_path_to_handle ( ( char * ) path , & dmhandle , & dmhandle_len ) ! = 0 ) {
DEBUG ( 2 , ( " dm_path_to_handle failed - assuming offline (%s) - %s \n " ,
path , strerror ( errno ) ) ) ;
2008-01-17 14:57:35 +03:00
offline = true ;
2008-01-16 12:26:35 +03:00
goto done ;
}
memset ( & dmname , 0 , sizeof ( dmname ) ) ;
2008-01-18 17:34:21 +03:00
strlcpy ( ( char * ) & dmname . an_chars [ 0 ] , tsmd - > attrib_name , sizeof ( dmname . an_chars ) ) ;
2008-01-16 12:26:35 +03:00
2008-04-08 15:17:53 +04:00
if ( tsmd - > attrib_value ! = NULL ) {
buflen = strlen ( tsmd - > attrib_value ) ;
} else {
buflen = 1 ;
}
buf = talloc_zero_size ( tsmd , buflen ) ;
if ( buf = = NULL ) {
DEBUG ( 0 , ( " out of memory in tsmsm_is_offline -- assuming online (%s) \n " , path ) ) ;
errno = ENOMEM ;
offline = false ;
goto done ;
}
2008-01-29 17:43:49 +03:00
do {
2008-08-24 07:53:19 +04:00
lerrno = 0 ;
2008-01-29 17:43:49 +03:00
ret = dm_get_dmattr ( * dmsession_id , dmhandle , dmhandle_len ,
2008-04-08 15:17:53 +04:00
DM_NO_TOKEN , & dmname , buflen , buf , & rlen ) ;
2008-01-29 17:43:49 +03:00
if ( ret = = - 1 & & errno = = EINVAL ) {
DEBUG ( 0 , ( " Stale DMAPI session, re-creating it. \n " ) ) ;
lerrno = EINVAL ;
if ( dmapi_new_session ( ) ) {
2008-01-29 18:33:22 +03:00
dmsession_id = dmapi_get_current_session ( ) ;
2008-01-29 17:43:49 +03:00
} else {
DEBUG ( 0 ,
( " Unable to re-create DMAPI session, assuming offline (%s) - %s \n " ,
path , strerror ( errno ) ) ) ;
offline = true ;
dm_handle_free ( dmhandle , dmhandle_len ) ;
goto done ;
}
}
} while ( ret = = - 1 & & lerrno = = EINVAL ) ;
2008-01-16 12:26:35 +03:00
2008-04-08 15:17:53 +04:00
/* check if we need a specific attribute value */
if ( tsmd - > attrib_value ! = NULL ) {
offline = ( ret = = 0 & & rlen = = buflen & &
memcmp ( buf , tsmd - > attrib_value , buflen ) = = 0 ) ;
} else {
/* its offline if the specified DMAPI attribute exists */
offline = ( ret = = 0 | | ( ret = = - 1 & & errno = = E2BIG ) ) ;
}
2008-01-16 12:26:35 +03:00
DEBUG ( 10 , ( " dm_get_dmattr %s ret=%d (%s) \n " , path , ret , strerror ( errno ) ) ) ;
ret = 0 ;
dm_handle_free ( dmhandle , dmhandle_len ) ;
done :
2008-04-08 15:17:53 +04:00
talloc_free ( buf ) ;
2008-01-16 12:26:35 +03:00
unbecome_root ( ) ;
2008-01-17 14:57:35 +03:00
return offline ;
2008-01-16 12:26:35 +03:00
}
static bool tsmsm_aio_force ( struct vfs_handle_struct * handle , struct files_struct * fsp )
{
SMB_STRUCT_STAT sbuf ;
struct tsmsm_struct * tsmd = ( struct tsmsm_struct * ) handle - > data ;
/* see if the file might be offline. This is called before each IO
to ensure we use AIO if the file is offline . We don ' t do the full dmapi
call as that would be too slow , instead we err on the side of using AIO
if the file might be offline
*/
if ( SMB_VFS_FSTAT ( fsp , & sbuf ) = = 0 ) {
2010-11-17 19:45:01 +03:00
DEBUG ( 10 , ( " tsmsm_aio_force st_blocks=%llu st_size=%llu "
" online_ratio=%.2f \n " , ( unsigned long long ) sbuf . st_ex_blocks ,
( unsigned long long ) sbuf . st_ex_size , tsmd - > online_ratio ) ) ;
2010-11-17 19:52:06 +03:00
return ! ( 512 * sbuf . st_ex_blocks > =
2009-05-14 17:34:42 +04:00
sbuf . st_ex_size * tsmd - > online_ratio ) ;
2008-01-16 12:26:35 +03:00
}
2008-01-17 07:34:33 +03:00
return false ;
2008-01-16 12:26:35 +03:00
}
2012-08-10 13:33:54 +04:00
struct tsmsm_pread_state {
struct files_struct * fsp ;
ssize_t ret ;
int err ;
2012-08-17 19:40:24 +04:00
bool was_offline ;
2012-08-10 13:33:54 +04:00
} ;
static void tsmsm_pread_done ( struct tevent_req * subreq ) ;
static struct tevent_req * tsmsm_pread_send ( struct vfs_handle_struct * handle ,
TALLOC_CTX * mem_ctx ,
struct tevent_context * ev ,
struct files_struct * fsp ,
void * data , size_t n , off_t offset )
2008-01-16 12:26:35 +03:00
{
2012-08-10 13:33:54 +04:00
struct tevent_req * req , * subreq ;
struct tsmsm_pread_state * state ;
2008-01-16 12:26:35 +03:00
2012-08-10 13:33:54 +04:00
req = tevent_req_create ( mem_ctx , & state , struct tsmsm_pread_state ) ;
if ( req = = NULL ) {
return NULL ;
}
state - > fsp = fsp ;
2012-08-17 19:40:24 +04:00
state - > was_offline = tsmsm_aio_force ( handle , fsp ) ;
2012-08-10 13:33:54 +04:00
subreq = SMB_VFS_NEXT_PREAD_SEND ( state , ev , handle , fsp , data ,
n , offset ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
}
tevent_req_set_callback ( subreq , tsmsm_pread_done , req ) ;
return req ;
}
static void tsmsm_pread_done ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct tsmsm_pread_state * state = tevent_req_data (
req , struct tsmsm_pread_state ) ;
state - > ret = SMB_VFS_PREAD_RECV ( subreq , & state - > err ) ;
TALLOC_FREE ( subreq ) ;
tevent_req_done ( req ) ;
}
static ssize_t tsmsm_pread_recv ( struct tevent_req * req , int * err )
{
struct tsmsm_pread_state * state = tevent_req_data (
req , struct tsmsm_pread_state ) ;
if ( tevent_req_is_unix_error ( req , err ) ) {
return - 1 ;
}
2012-08-17 19:40:24 +04:00
if ( state - > ret > = 0 & & state - > was_offline ) {
2012-08-10 13:33:54 +04:00
struct files_struct * fsp = state - > fsp ;
notify_fname ( fsp - > conn , NOTIFY_ACTION_MODIFIED ,
2008-01-16 12:26:35 +03:00
FILE_NOTIFY_CHANGE_ATTRIBUTES ,
2009-07-11 05:11:32 +04:00
fsp - > fsp_name - > base_name ) ;
2008-01-16 12:26:35 +03:00
}
2012-08-10 13:33:54 +04:00
* err = state - > err ;
return state - > ret ;
}
2008-01-16 12:26:35 +03:00
2012-08-10 13:33:54 +04:00
struct tsmsm_pwrite_state {
struct files_struct * fsp ;
ssize_t ret ;
int err ;
2012-08-17 19:40:24 +04:00
bool was_offline ;
2012-08-10 13:33:54 +04:00
} ;
static void tsmsm_pwrite_done ( struct tevent_req * subreq ) ;
static struct tevent_req * tsmsm_pwrite_send ( struct vfs_handle_struct * handle ,
TALLOC_CTX * mem_ctx ,
struct tevent_context * ev ,
struct files_struct * fsp ,
const void * data , size_t n ,
off_t offset )
{
struct tevent_req * req , * subreq ;
struct tsmsm_pwrite_state * state ;
req = tevent_req_create ( mem_ctx , & state , struct tsmsm_pwrite_state ) ;
if ( req = = NULL ) {
return NULL ;
}
state - > fsp = fsp ;
2012-08-17 19:40:24 +04:00
state - > was_offline = tsmsm_aio_force ( handle , fsp ) ;
2012-08-10 13:33:54 +04:00
subreq = SMB_VFS_NEXT_PWRITE_SEND ( state , ev , handle , fsp , data ,
n , offset ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
}
tevent_req_set_callback ( subreq , tsmsm_pwrite_done , req ) ;
return req ;
}
static void tsmsm_pwrite_done ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct tsmsm_pwrite_state * state = tevent_req_data (
req , struct tsmsm_pwrite_state ) ;
state - > ret = SMB_VFS_PWRITE_RECV ( subreq , & state - > err ) ;
TALLOC_FREE ( subreq ) ;
tevent_req_done ( req ) ;
}
static ssize_t tsmsm_pwrite_recv ( struct tevent_req * req , int * err )
{
struct tsmsm_pwrite_state * state = tevent_req_data (
req , struct tsmsm_pwrite_state ) ;
if ( tevent_req_is_unix_error ( req , err ) ) {
return - 1 ;
}
2012-08-17 19:40:24 +04:00
if ( state - > ret > = 0 & & state - > was_offline ) {
2012-08-10 13:33:54 +04:00
struct files_struct * fsp = state - > fsp ;
notify_fname ( fsp - > conn , NOTIFY_ACTION_MODIFIED ,
FILE_NOTIFY_CHANGE_ATTRIBUTES ,
fsp - > fsp_name - > base_name ) ;
}
* err = state - > err ;
return state - > ret ;
2008-01-16 12:26:35 +03:00
}
static ssize_t tsmsm_sendfile ( vfs_handle_struct * handle , int tofd , files_struct * fsp , const DATA_BLOB * hdr ,
2012-04-05 08:53:08 +04:00
off_t offset , size_t n )
2008-01-16 12:26:35 +03:00
{
2008-08-23 05:36:27 +04:00
bool file_offline = tsmsm_aio_force ( handle , fsp ) ;
2008-01-16 12:26:35 +03:00
2008-08-23 05:36:27 +04:00
if ( file_offline ) {
DEBUG ( 10 , ( " tsmsm_sendfile on offline file - rejecting \n " ) ) ;
errno = ENOSYS ;
return - 1 ;
}
2008-01-16 12:26:35 +03:00
return SMB_VFS_NEXT_SENDFILE ( handle , tofd , fsp , hdr , offset , n ) ;
}
/* We do overload pread to allow notification when file becomes online after offline status */
/* We don't intercept SMB_VFS_READ here because all file I/O now goes through SMB_VFS_PREAD instead */
static ssize_t tsmsm_pread ( struct vfs_handle_struct * handle , struct files_struct * fsp ,
2012-04-05 08:53:08 +04:00
void * data , size_t n , off_t offset ) {
2008-01-16 12:26:35 +03:00
ssize_t result ;
bool notify_online = tsmsm_aio_force ( handle , fsp ) ;
result = SMB_VFS_NEXT_PREAD ( handle , fsp , data , n , offset ) ;
if ( ( result ! = - 1 ) & & notify_online ) {
/* We can't actually force AIO at this point (came here not from reply_read_and_X)
what we can do is to send notification that file became online
*/
notify_fname ( handle - > conn , NOTIFY_ACTION_MODIFIED ,
FILE_NOTIFY_CHANGE_ATTRIBUTES ,
2009-07-11 05:11:32 +04:00
fsp - > fsp_name - > base_name ) ;
2008-01-16 12:26:35 +03:00
}
return result ;
}
static ssize_t tsmsm_pwrite ( struct vfs_handle_struct * handle , struct files_struct * fsp ,
2012-04-05 08:53:08 +04:00
const void * data , size_t n , off_t offset ) {
2008-01-16 12:26:35 +03:00
ssize_t result ;
bool notify_online = tsmsm_aio_force ( handle , fsp ) ;
result = SMB_VFS_NEXT_PWRITE ( handle , fsp , data , n , offset ) ;
if ( ( result ! = - 1 ) & & notify_online ) {
/* We can't actually force AIO at this point (came here not from reply_read_and_X)
what we can do is to send notification that file became online
*/
notify_fname ( handle - > conn , NOTIFY_ACTION_MODIFIED ,
FILE_NOTIFY_CHANGE_ATTRIBUTES ,
2009-07-11 05:11:32 +04:00
fsp - > fsp_name - > base_name ) ;
2008-01-16 12:26:35 +03:00
}
return result ;
}
2008-01-17 07:34:33 +03:00
static int tsmsm_set_offline ( struct vfs_handle_struct * handle ,
2011-02-25 16:43:52 +03:00
const struct smb_filename * fname )
{
2008-01-16 12:26:35 +03:00
struct tsmsm_struct * tsmd = ( struct tsmsm_struct * ) handle - > data ;
int result = 0 ;
char * command ;
2011-02-25 16:43:52 +03:00
NTSTATUS status ;
char * path ;
2008-01-16 12:26:35 +03:00
2008-01-18 17:34:21 +03:00
if ( tsmd - > hsmscript = = NULL ) {
/* no script enabled */
2008-08-23 05:36:27 +04:00
DEBUG ( 1 , ( " tsmsm_set_offline: No 'tsmsm:hsm script' configured \n " ) ) ;
2008-01-18 17:34:21 +03:00
return 0 ;
}
2011-02-25 16:43:52 +03:00
status = get_full_smb_filename ( talloc_tos ( ) , fname , & path ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
errno = map_errno_from_nt_status ( status ) ;
return false ;
}
2008-01-16 12:26:35 +03:00
/* Now, call the script */
command = talloc_asprintf ( tsmd , " %s offline \" %s \" " , tsmd - > hsmscript , path ) ;
if ( ! command ) {
DEBUG ( 1 , ( " tsmsm_set_offline: can't allocate memory to run hsm script " ) ) ;
return - 1 ;
}
DEBUG ( 10 , ( " tsmsm_set_offline: Running [%s] \n " , command ) ) ;
if ( ( result = smbrun ( command , NULL ) ) ! = 0 ) {
DEBUG ( 1 , ( " tsmsm_set_offline: Running [%s] returned %d \n " , command , result ) ) ;
}
TALLOC_FREE ( command ) ;
return result ;
}
2009-08-25 07:57:37 +04:00
static uint32_t tsmsm_fs_capabilities ( struct vfs_handle_struct * handle ,
enum timestamp_set_resolution * p_ts_res )
2008-01-17 16:51:14 +03:00
{
2009-08-25 07:57:37 +04:00
return SMB_VFS_NEXT_FS_CAPABILITIES ( handle , p_ts_res ) | FILE_SUPPORTS_REMOTE_STORAGE | FILE_SUPPORTS_REPARSE_POINTS ;
2008-01-16 12:26:35 +03:00
}
2009-07-24 04:28:58 +04:00
static struct vfs_fn_pointers tsmsm_fns = {
2009-08-02 18:42:49 +04:00
. connect_fn = tsmsm_connect ,
2011-12-04 08:45:04 +04:00
. fs_capabilities_fn = tsmsm_fs_capabilities ,
. aio_force_fn = tsmsm_aio_force ,
. pread_fn = tsmsm_pread ,
2012-08-10 13:33:54 +04:00
. pread_send_fn = tsmsm_pread_send ,
. pread_recv_fn = tsmsm_pread_recv ,
2011-12-04 08:45:04 +04:00
. pwrite_fn = tsmsm_pwrite ,
2012-08-10 13:33:54 +04:00
. pwrite_send_fn = tsmsm_pwrite_send ,
. pwrite_recv_fn = tsmsm_pwrite_recv ,
2011-12-04 08:45:04 +04:00
. sendfile_fn = tsmsm_sendfile ,
. is_offline_fn = tsmsm_is_offline ,
. set_offline_fn = tsmsm_set_offline ,
2008-01-16 12:26:35 +03:00
} ;
NTSTATUS vfs_tsmsm_init ( void ) ;
NTSTATUS vfs_tsmsm_init ( void )
{
return smb_register_vfs ( SMB_VFS_INTERFACE_VERSION ,
2009-09-17 04:06:30 +04:00
" tsmsm " , & tsmsm_fns ) ;
2008-01-16 12:26:35 +03:00
}