06f4b16ac10c41992279de4c7835035a60eb7df7
[ira/wip.git] / source3 / modules / onefs_config.c
1 /*
2  * Unix SMB/CIFS implementation.
3  * Support for OneFS
4  *
5  * Copyright (C) Todd Stecher, 2009
6  * Copyright (C) Tim Prouty, 2009
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "includes.h"
23 #include "onefs_config.h"
24
25 #include <ifs/ifs_syscalls.h>
26
27 #define ONEFS_DATA_FASTBUF      10
28
29 struct onefs_vfs_share_config vfs_share_config[ONEFS_DATA_FASTBUF];
30 struct onefs_vfs_share_config *pvfs_share_config;
31
32 static void onefs_load_faketimestamp_config(struct connection_struct *conn,
33                                             struct onefs_vfs_share_config *cfg)
34 {
35         const char **parm;
36         int snum = SNUM(conn);
37
38         parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_NOW,
39                                    PARM_ATIME_NOW_DEFAULT);
40
41         if (parm) {
42                 cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
43                 set_namearray(&cfg->atime_now_list,*parm);
44         }
45
46         parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_CTIME_NOW,
47                                    PARM_CTIME_NOW_DEFAULT);
48
49         if (parm) {
50                 cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
51                 set_namearray(&cfg->ctime_now_list,*parm);
52         }
53
54         parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_MTIME_NOW,
55                                    PARM_MTIME_NOW_DEFAULT);
56
57         if (parm) {
58                 cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
59                 set_namearray(&cfg->mtime_now_list,*parm);
60         }
61
62         parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_STATIC,
63                                    PARM_ATIME_STATIC_DEFAULT);
64
65         if (parm) {
66                 cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
67                 set_namearray(&cfg->atime_static_list,*parm);
68         }
69
70         parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_MTIME_STATIC,
71                                    PARM_MTIME_STATIC_DEFAULT);
72
73         if (parm) {
74                 cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
75                 set_namearray(&cfg->mtime_static_list,*parm);
76         }
77
78         cfg->atime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_ATIME_SLOP,
79                                       PARM_ATIME_SLOP_DEFAULT);
80         cfg->ctime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_CTIME_SLOP,
81                                       PARM_CTIME_SLOP_DEFAULT);
82         cfg->mtime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_MTIME_SLOP,
83                                       PARM_MTIME_SLOP_DEFAULT);
84 }
85
86 /**
87  * Set onefs-specific vfs global config parameters.
88  *
89  * Since changes in these parameters require calling syscalls, we only want to
90  * call them when the configuration actually changes.
91  */
92 static void onefs_load_global_config(connection_struct *conn)
93 {
94         static struct onefs_vfs_global_config global_config;
95         bool dot_snap_child_accessible;
96         bool dot_snap_child_visible;
97         bool dot_snap_root_accessible;
98         bool dot_snap_root_visible;
99         bool dot_snap_tilde;
100         bool reconfig_dso = false;
101         bool reconfig_tilde = false;
102
103         /* Check if this is the first time setting the config options. */
104         if (!(global_config.init_flags & ONEFS_VFS_CONFIG_INITIALIZED)) {
105                 global_config.init_flags |= ONEFS_VFS_CONFIG_INITIALIZED;
106
107                 /* Set process encoding */
108                 onefs_sys_config_enc();
109
110                 reconfig_dso = true;
111                 reconfig_tilde = true;
112         }
113
114         /* Get the dot snap options from the conf. */
115         dot_snap_child_accessible =
116             lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
117                          PARM_DOT_SNAP_CHILD_ACCESSIBLE,
118                          PARM_DOT_SNAP_CHILD_ACCESSIBLE_DEFAULT);
119         dot_snap_child_visible =
120             lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
121                          PARM_DOT_SNAP_CHILD_VISIBLE,
122                          PARM_DOT_SNAP_CHILD_VISIBLE_DEFAULT);
123         dot_snap_root_accessible =
124             lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
125                          PARM_DOT_SNAP_ROOT_ACCESSIBLE,
126                          PARM_DOT_SNAP_ROOT_ACCESSIBLE_DEFAULT);
127         dot_snap_root_visible =
128             lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
129                          PARM_DOT_SNAP_ROOT_VISIBLE,
130                          PARM_DOT_SNAP_ROOT_VISIBLE_DEFAULT);
131         dot_snap_tilde =
132             lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
133                          PARM_DOT_SNAP_TILDE,
134                          PARM_DOT_SNAP_TILDE_DEFAULT);
135
136         /* Check if any of the dot snap options need updating. */
137         if (dot_snap_child_accessible !=
138             global_config.dot_snap_child_accessible) {
139                 global_config.dot_snap_child_accessible =
140                     dot_snap_child_accessible;
141                 reconfig_dso = true;
142         }
143         if (dot_snap_child_visible !=
144             global_config.dot_snap_child_visible) {
145                 global_config.dot_snap_child_visible =
146                     dot_snap_child_visible;
147                 reconfig_dso = true;
148         }
149         if (dot_snap_root_accessible !=
150             global_config.dot_snap_root_accessible) {
151                 global_config.dot_snap_root_accessible =
152                     dot_snap_root_accessible;
153                 reconfig_dso = true;
154         }
155         if (dot_snap_root_visible !=
156             global_config.dot_snap_root_visible) {
157                 global_config.dot_snap_root_visible =
158                     dot_snap_root_visible;
159                 reconfig_dso = true;
160         }
161         if (dot_snap_tilde != global_config.dot_snap_tilde) {
162                 global_config.dot_snap_tilde = dot_snap_tilde;
163                 reconfig_tilde = true;
164         }
165
166         /* If a dot snap option has changed update the process.  */
167         if (reconfig_dso) {
168                 onefs_sys_config_snap_opt(&global_config);
169         }
170
171         /* If the dot snap tilde option has changed update the process.  */
172         if (reconfig_tilde) {
173                 onefs_sys_config_tilde(&global_config);
174         }
175 }
176
177 int onefs_load_config(connection_struct *conn)
178 {
179         int snum = SNUM(conn);
180         int share_count = lp_numservices();
181
182         /* Share config */
183         if (!pvfs_share_config) {
184
185                 if (share_count <= ONEFS_DATA_FASTBUF)
186                         pvfs_share_config = vfs_share_config;
187                 else {
188                         pvfs_share_config =
189                             SMB_MALLOC_ARRAY(struct onefs_vfs_share_config,
190                                              share_count);
191                         if (!pvfs_share_config) {
192                                 errno = ENOMEM;
193                                 return -1;
194                         }
195
196                         memset(pvfs_share_config, 0,
197                             (sizeof(struct onefs_vfs_share_config) *
198                                     share_count));
199                 }
200         }
201
202         if ((pvfs_share_config[snum].init_flags &
203                 ONEFS_VFS_CONFIG_INITIALIZED) == 0) {
204                         pvfs_share_config[snum].init_flags =
205                             ONEFS_VFS_CONFIG_INITIALIZED;
206                         onefs_load_faketimestamp_config(conn,
207                                                         &pvfs_share_config[snum]);
208         }
209
210         /* Global config */
211         onefs_load_global_config(conn);
212
213         return 0;
214 }
215
216 bool onefs_get_config(int snum, int config_type,
217                       struct onefs_vfs_share_config *cfg)
218 {
219         if (vfs_share_config[snum].init_flags & config_type)
220                 *cfg = vfs_share_config[snum];
221         else
222                 return false;
223
224         return true;
225 }
226
227
228 /**
229  * Set the per-process encoding, ignoring errors.
230  */
231 void onefs_sys_config_enc(void)
232 {
233         int ret;
234
235         ret = enc_set_proc(ENC_UTF8);
236         if (ret) {
237                 DEBUG(0, ("Setting process encoding failed: %s",
238                         strerror(errno)));
239         }
240 }
241
242 /**
243  * Set the per-process .snpashot directory options, ignoring errors.
244  */
245 void onefs_sys_config_snap_opt(struct onefs_vfs_global_config *global_config)
246 {
247         struct ifs_dotsnap_options dso;
248         int ret;
249
250         dso.per_proc = 1;
251         dso.sub_accessible = global_config->dot_snap_child_accessible;
252         dso.sub_visible = global_config->dot_snap_child_visible;
253         dso.root_accessible = global_config->dot_snap_root_accessible;
254         dso.root_visible = global_config->dot_snap_root_visible;
255
256         ret = ifs_set_dotsnap_options(&dso);
257         if (ret) {
258                 DEBUG(0, ("Setting snapshot visibility/accessibility "
259                         "failed: %s", strerror(errno)));
260         }
261 }
262
263 /**
264  * Set the per-process flag saying whether or not to accept ~snapshot
265  * as an alternative name for .snapshot directories.
266  */
267 void onefs_sys_config_tilde(struct onefs_vfs_global_config *global_config)
268 {
269         int ret;
270
271         ret = ifs_tilde_snapshot(global_config->dot_snap_tilde);
272         if (ret) {
273                 DEBUG(0, ("Setting snapshot tilde failed: %s",
274                         strerror(errno)));
275         }
276 }