1 /*
2  * Copyright 2017 Skytechnology sp. z o.o..
3  * Author: Piotr Sarna <sarna@skytechnology.pl>
4  *
5  * LizardFS C API
6  *
7  * This library can be used to communicate with LizardFS metadata and data
8  * servers from C/C++ code.
9  *
10  * Compile with -llizardfs-client and LizardFS C/C++ library installed.
11  */
12 
13 #include <fcntl.h>
14 #include <stdint.h>
15 #include <unistd.h>
16 #include <sys/stat.h>
17 #include <sys/uio.h>
18 
19 #ifndef __LIZARDFS_C_API_H
20 #define __LIZARDFS_C_API_H
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #else
25 #include <stdbool.h>
26 #endif
27 
28 enum liz_sugid_clear_mode {
29 	LIZARDFS_SUGID_CLEAR_MODE_NEVER,
30 	LIZARDFS_SUGID_CLEAR_MODE_ALWAYS,
31 	LIZARDFS_SUGID_CLEAR_MODE_OSX,
32 	LIZARDFS_SUGID_CLEAR_MODE_BSD,
33 	LIZARDFS_SUGID_CLEAR_MODE_EXT,
34 	LIZARDFS_SUGID_CLEAR_MODE_XFS,
35 	LIZARDFS_SUGID_CLEAR_MODE_END_
36 };
37 
38 typedef struct liz_init_params {
39 	const char *bind_host;
40 	const char *host;
41 	const char *port;
42 	bool meta;
43 	const char *mountpoint;
44 	const char *subfolder;
45 	const char *password;
46 	const char *md5_pass;
47 	bool do_not_remember_password;
48 	bool delayed_init;
49 	unsigned report_reserved_period;
50 
51 	unsigned io_retries;
52 	unsigned chunkserver_round_time_ms;
53 	unsigned chunkserver_connect_timeout_ms;
54 	unsigned chunkserver_wave_read_timeout_ms;
55 	unsigned total_read_timeout_ms;
56 	unsigned cache_expiration_time_ms;
57 	unsigned readahead_max_window_size_kB;
58 	bool prefetch_xor_stripes;
59 	double bandwidth_overuse;
60 
61 	unsigned write_cache_size;
62 	unsigned write_workers;
63 	unsigned write_window_size;
64 	unsigned chunkserver_write_timeout_ms;
65 	unsigned cache_per_inode_percentage;
66 	unsigned symlink_cache_timeout_s;
67 
68 	bool debug_mode;
69 	int keep_cache;
70 	double direntry_cache_timeout;
71 	unsigned direntry_cache_size;
72 	double entry_cache_timeout;
73 	double attr_cache_timeout;
74 	bool mkdir_copy_sgid;
75 	enum liz_sugid_clear_mode sugid_clear_mode;
76 	bool use_rw_lock;
77 	double acl_cache_timeout;
78 	unsigned acl_cache_size;
79 
80 	bool verbose;
81 
82 	const char *io_limits_config_file;
83 } liz_init_params_t;
84 
85 #define LIZARDFS_MAX_GOAL_NAME 64
86 #define LIZARDFS_MAX_READLINK_LENGTH 65535
87 
88 typedef uint32_t liz_inode_t;
89 typedef int liz_err_t;
90 struct liz;
91 typedef struct liz liz_t;
92 struct liz_fileinfo;
93 typedef struct liz_fileinfo liz_fileinfo_t;
94 struct liz_context;
95 typedef struct liz_context liz_context_t;
96 typedef struct liz_acl liz_acl_t;
97 
98 #define LIZ_SET_ATTR_MODE      (1 << 0)
99 #define LIZ_SET_ATTR_UID       (1 << 1)
100 #define LIZ_SET_ATTR_GID       (1 << 2)
101 #define LIZ_SET_ATTR_SIZE      (1 << 3)
102 #define LIZ_SET_ATTR_ATIME     (1 << 4)
103 #define LIZ_SET_ATTR_MTIME     (1 << 5)
104 #define LIZ_SET_ATTR_ATIME_NOW (1 << 7)
105 #define LIZ_SET_ATTR_MTIME_NOW (1 << 8)
106 
107 /* ACL flags */
108 #define LIZ_ACL_AUTO_INHERIT 0x01
109 #define LIZ_ACL_PROTECTED 0x02
110 #define LIZ_ACL_DEFAULTED 0x04
111 #define LIZ_ACL_WRITE_THROUGH 0x40
112 #define LIZ_ACL_MASKED 0x80
113 
114 /* ACL ace types */
115 #define LIZ_ACL_ACCESS_ALLOWED_ACE_TYPE 0x0000
116 #define LIZ_ACL_ACCESS_DENIED_ACE_TYPE 0x0001
117 
118 /* ACL ace flags bits */
119 #define LIZ_ACL_FILE_INHERIT_ACE 0x0001
120 #define LIZ_ACL_DIRECTORY_INHERIT_ACE 0x0002
121 #define LIZ_ACL_NO_PROPAGATE_INHERIT_ACE 0x0004
122 #define LIZ_ACL_INHERIT_ONLY_ACE 0x0008
123 #define LIZ_ACL_SUCCESSFUL_ACCESS_ACE_FLAG 0x00000010
124 #define LIZ_ACL_FAILED_ACCESS_ACE_FLAG 0x00000020
125 #define LIZ_ACL_IDENTIFIER_GROUP 0x0040
126 #define LIZ_ACL_INHERITED_ACE 0x0080  /* non nfs4 */
127 #define LIZ_ACL_SPECIAL_WHO 0x0100    /* lizardfs */
128 
129 /* ACL ace mask bits */
130 #define LIZ_ACL_READ_DATA 0x00000001
131 #define LIZ_ACL_LIST_DIRECTORY 0x00000001
132 #define LIZ_ACL_WRITE_DATA 0x00000002
133 #define LIZ_ACL_ADD_FILE 0x00000002
134 #define LIZ_ACL_APPEND_DATA 0x00000004
135 #define LIZ_ACL_ADD_SUBDIRECTORY 0x00000004
136 #define LIZ_ACL_READ_NAMED_ATTRS 0x00000008
137 #define LIZ_ACL_WRITE_NAMED_ATTRS 0x00000010
138 #define LIZ_ACL_EXECUTE 0x00000020
139 #define LIZ_ACL_DELETE_CHILD 0x00000040
140 #define LIZ_ACL_READ_ATTRIBUTES 0x00000080
141 #define LIZ_ACL_WRITE_ATTRIBUTES 0x00000100
142 #define LIZ_ACL_WRITE_RETENTION 0x00000200
143 #define LIZ_ACL_WRITE_RETENTION_HOLD 0x00000400
144 #define LIZ_ACL_DELETE 0x00010000
145 #define LIZ_ACL_READ_ACL 0x00020000
146 #define LIZ_ACL_WRITE_ACL 0x00040000
147 #define LIZ_ACL_WRITE_OWNER 0x00080000
148 #define LIZ_ACL_SYNCHRONIZE 0x00100000
149 
150 /* ACL ace special ids */
151 #define LIZ_ACL_OWNER_SPECIAL_ID 0x0
152 #define LIZ_ACL_GROUP_SPECIAL_ID 0x1
153 #define LIZ_ACL_EVERYONE_SPECIAL_ID 0x2
154 
155 /* ACL helper macros */
156 #define LIZ_ACL_POSIX_MODE_READ (LIZ_ACL_READ_DATA | LIZ_ACL_LIST_DIRECTORY)
157 #define LIZ_ACL_POSIX_MODE_WRITE (LIZ_ACL_WRITE_DATA | LIZ_ACL_ADD_FILE \
158 	| LIZ_ACL_APPEND_DATA | LIZ_ACL_ADD_SUBDIRECTORY | LIZ_ACL_DELETE_CHILD)
159 #define LIZ_ACL_POSIX_MODE_EXECUTE (EXECUTE)
160 #define LIZ_ACL_POSIX_MODE_ALL (LIZ_ACL_POSIX_MODE_READ | LIZ_ACL_POSIX_MODE_WRITE \
161 	| LIZ_POSIX_MODE_EXEC)
162 
163 enum liz_special_ino {
164 	LIZARDFS_INODE_ERROR = 0,
165 	LIZARDFS_INODE_ROOT = 1,
166 };
167 
168 enum liz_setxattr_mode {
169 	XATTR_SMODE_CREATE_OR_REPLACE = 0,
170 	XATTR_SMODE_CREATE_ONLY       = 1,
171 	XATTR_SMODE_REPLACE_ONLY      = 2,
172 	XATTR_SMODE_REMOVE            = 3,
173 };
174 
175 /* Basic attributes of a file */
176 typedef struct liz_entry {
177 	liz_inode_t ino;
178 	unsigned long generation;
179 	struct stat attr;
180 	double attr_timeout;
181 	double entry_timeout;
182 } liz_entry_t;
183 
184 /* Result of setattr/getattr operations */
185 typedef struct liz_attr_reply {
186 	struct stat attr;
187 	double attr_timeout;
188 } liz_attr_reply_t;
189 
190 /* Basic attributes of a directory */
191 typedef struct liz_direntry {
192 	char *name;
193 	struct stat attr;
194 	off_t next_entry_offset;
195 } liz_direntry_t;
196 
197 typedef struct liz_namedinode_entry {
198 	liz_inode_t ino;
199 	char *name;
200 } liz_namedinode_entry_t;
201 
202 /* Result of getxattr, setxattr and listattr operations */
203 typedef struct liz_xattr_reply {
204 	uint32_t value_length;
205 	uint8_t *value_buffer;
206 } liz_xattr_reply_t;
207 
208 /* Result of statfs operation
209  * total_space - total space
210  * avail_space - available space
211  * trash_space - space occupied by trash files
212  * reserved_space - space occupied by reserved files
213  * inodes - number of inodes
214  */
215 typedef struct liz_stat {
216 	uint64_t total_space;
217 	uint64_t avail_space;
218 	uint64_t trash_space;
219 	uint64_t reserved_space;
220 	uint32_t inodes;
221 } liz_stat_t;
222 
223 /* Server location for a chunk part */
224 typedef struct liz_chunk_part_info {
225 	uint32_t addr;
226 	uint16_t port;
227 	uint16_t part_type_id;
228 	char *label;
229 } liz_chunk_part_info_t;
230 
231 /* Chunk information including id, type and all parts */
232 typedef struct liz_chunk_info {
233 	uint64_t chunk_id;
234 	uint32_t chunk_version;
235 	uint32_t parts_size;
236 	liz_chunk_part_info_t *parts;
237 } liz_chunk_info_t;
238 
239 typedef struct liz_chunkserver_info {
240 	uint32_t version;
241 	uint32_t ip;
242 	uint16_t port;
243 	uint64_t used_space;
244 	uint64_t total_space;
245 	uint32_t chunks_count;
246 	uint32_t error_counter;
247 	char *label;
248 } liz_chunkserver_info_t;
249 
250 typedef struct liz_acl_ace {
251 	uint16_t type;
252 	uint16_t flags;
253 	uint32_t mask;
254 	uint32_t id;
255 } liz_acl_ace_t;
256 
257 typedef struct liz_lock_info {
258 	int16_t l_type;   // Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.
259 	int64_t l_start;  // Offset where the lock begins.
260 	int64_t l_len;    // Size of the locked area; zero means until EOF.
261 	int32_t l_pid;    // Process holding the lock.
262 } liz_lock_info_t;
263 
264 typedef struct liz_lock_interrupt_info {
265 	uint64_t owner;
266 	uint32_t ino;
267 	uint32_t reqid;
268 } liz_lock_interrupt_info_t;
269 
270 /*!
271  * \brief Function that registers lock interrupt data.
272  * \param info lock info to be remembered somewhere
273  * \param priv private data potentially needed by caller
274  */
275 typedef int (*liz_lock_register_interrupt_t)(struct liz_lock_interrupt_info *info, void *priv);
276 
277 /*!
278  * \brief Create a context for LizardFS operations
279  *  Flavor 1: create default context with current uid/gid/pid
280  *  Flavor 2: create context with custom uid/gid/pid
281  *
282  *  \warning Creating context with secondary groups involves calling liz_update_groups
283  *  on a created context. It is the case because metadata server needs to be notified
284  *  that new group set was created. If secondary groups are registered by calling
285  *  liz_update_groups(ctx, instance), context is bound to instance it was registered with
286  *  and should not be used with other instances.
287  */
288 liz_context_t *liz_create_context();
289 liz_context_t *liz_create_user_context(uid_t uid, gid_t gid, pid_t pid, mode_t umask);
290 
291 /*!
292  * \brief Set lock owner inside a fileinfo structure
293  * \param fileinfo descriptor to an open file
294  * \param lock_owner lock owner token
295  */
296 void liz_set_lock_owner(liz_fileinfo_t *fileinfo, uint64_t lock_owner);
297 
298 /*!
299  * \brief Returns last error code set by specific calls (see below)
300  */
301 liz_err_t liz_last_err();
302 
303 /*!
304  * \brief Converts native LizardFS error code to POSIX error code.
305  */
306 int liz_error_conv(liz_err_t lizardfs_error_code);
307 
308 /*!
309  * \brief Returns human-readable description of LizardFS error code
310  */
311 const char *liz_error_string(liz_err_t lizardfs_error_code);
312 
313 /*!
314  * \brief Destroy a context for LizardFS operations
315  */
316 void liz_destroy_context(liz_context_t *ctx);
317 
318 /*!
319  * \brief Initialize init params to defaults
320  * \param host master server connection host
321  * \param port master server connection port
322  * \param mountpoint a human-readable name for 'mountpoint' created by a connection
323  */
324 void liz_set_default_init_params(struct liz_init_params *params,
325 		const char *host, const char *port, const char *mountpoint);
326 
327 /*!
328  * \brief Initialize a connection with master server
329  * \param host master server connection host
330  * \param port master server connection port
331  * \param mountpoint a human-readable name for 'mountpoint' created by a connection
332  * \return a LizardFS client instance, nullptr if connection is impossible,
333  *  sets last error code (check with liz_last_err())
334  */
335 liz_t *liz_init(const char *host, const char *port, const char *mountpoint);
336 
337 /*!
338  * \brief Initialize a connection with master server
339  * \param params init params initialized via liz_set_default_init_params()
340  *        and possibly tweaked
341  * \return a LizardFS client instance, nullptr if connection is impossible,
342  *  sets last error code (check with liz_last_err())
343  */
344 liz_t *liz_init_with_params(struct liz_init_params *params);
345 
346 /*!
347  * \brief Update secondary group information in context
348  * \param instance instance returned from liz_init
349  * \param ctx context to be updated
350  * \param gids array of new group ids to be set
351  * \param gid_num length of gids array
352  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
353  */
354 int liz_update_groups(liz_t *instance, liz_context_t *ctx, gid_t *gids, int gid_num);
355 
356 /*! \brief Find inode in parent directory by name
357  * \param instance instance returned from liz_init
358  * \param ctx context returned from liz_create_context
359  * \param parent parent inode
360  * \param path name to be looked up
361  * \param entry structure to be filled with lookup result
362  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
363  */
364 int liz_lookup(liz_t *instance, liz_context_t *ctx, liz_inode_t parent, const char *path,
365 	       struct liz_entry *entry);
366 
367 /*! \brief Create a file with given parent and name
368  * \param instance instance returned from liz_init
369  * \param ctx context returned from liz_create_context
370  * \param parent parent inode
371  * \param path name to be looked up
372  * \param mode file permissions and node type
373  * \param rdev major/minor numbers for block devices, otherwise ignored
374  * \param entry filled upon successful creation
375  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
376  */
377 int liz_mknod(liz_t *instance, liz_context_t *ctx, liz_inode_t parent, const char *path,
378 	      mode_t mode, dev_t rdev, struct liz_entry *entry);
379 
380 /*! \brief Create a link with given parent and name
381  * \param instance instance returned from liz_init
382  * \param ctx context returned from liz_create_context
383  * \param inode target inode
384  * \param parent parent inode
385  * \param name link name (no paths allowed)
386  * \param entry filled upon successful creation
387  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
388  */
389 int liz_link(liz_t *instance, liz_context_t *ctx, liz_inode_t inode, liz_inode_t parent,
390 	      const char *name, struct liz_entry *entry);
391 
392 /*! \brief Create a symlink with given parent and name
393  * \param instance instance returned from liz_init
394  * \param ctx context returned from liz_create_context
395  * \param link link contents (path it points to)
396  * \param parent parent inode
397  * \param name link name (no paths allowed)
398  * \param entry filled upon successful creation
399  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
400  */
401 int liz_symlink(liz_t *instance, liz_context_t *ctx, const char *link, liz_inode_t parent,
402 	      const char *name, struct liz_entry *entry);
403 
404 /*! \brief Open a file by inode
405  * \param instance instance returned from liz_init
406  * \param ctx context returned from liz_create_context
407  * \param inode inode of a file
408  * \param flags open flags
409  * \return fileinfo descriptor of an open file,
410  *  if failed - nullptr and sets last error code (check with liz_last_err())
411  */
412 liz_fileinfo_t *liz_open(liz_t *instance, liz_context_t *ctx, liz_inode_t inode, int flags);
413 
414 /*! \brief Read bytes from open file
415  * \param instance instance returned from liz_init
416  * \param ctx context returned from liz_create_context
417  * \param fileinfo descriptor of an open file
418  * \param offset read offset
419  * \param size read size
420  * \param buffer buffer to be read to
421  * \return number of bytes read on success,
422  *  -1 if failed and sets last error code (check with liz_last_err())
423  */
424 ssize_t liz_read(liz_t *instance, liz_context_t *ctx, liz_fileinfo_t *fileinfo, off_t offset,
425 	         size_t size, char *buffer);
426 ssize_t liz_readv(liz_t *instance, liz_context_t *ctx, liz_fileinfo_t *fileinfo, off_t offset,
427 	          size_t size, const struct iovec *iov, int iovcnt);
428 
429 /*! \brief Write bytes to open file
430  * \param instance instance returned from liz_init
431  * \param ctx context returned from liz_create_context
432  * \param fileinfo descriptor of an open file
433  * \param offset write offset
434  * \param size write size
435  * \param buffer buffer to be written from
436  * \return number of bytes written on success,
437  *  -1 if failed and sets last error code (check with liz_last_err())
438  */
439 ssize_t liz_write(liz_t *instance, liz_context_t *ctx, liz_fileinfo_t *fileinfo,
440 	          off_t offset, size_t size, const char *buffer);
441 
442 /*! \brief Release a previously open file
443  * \param instance instance returned from liz_init
444  * \param fileinfo descriptor of an open file
445  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
446  */
447 int liz_release(liz_t *instance, liz_fileinfo_t *fileinfo);
448 
449 /*! \brief Flush data written to an open file
450  * \param instance instance returned from liz_init
451  * \param ctx context returned from liz_create_context
452  * \param fileinfo descriptor of an open file
453  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
454  */
455 int liz_flush(liz_t *instance, liz_context_t *ctx, liz_fileinfo_t *fileinfo);
456 
457 /*! \brief Get attributes by inode
458  * \param instance instance returned from liz_init
459  * \param ctx context returned from liz_create_context
460  * \param inode inode of a file
461  * \param reply structure to be filled with getattr result
462  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
463  */
464 int liz_getattr(liz_t *instance, liz_context_t *ctx, liz_inode_t inode,
465 	        struct liz_attr_reply *reply);
466 
467 /*! \brief End a connection with master server
468  * \param instance instance returned from liz_init
469  */
470 void liz_destroy(liz_t *instance);
471 
472 /*! \brief Open a directory
473  * \param instance instance returned from liz_init
474  * \param ctx context returned from liz_create_context
475  * \param inode inode of a directory
476  * \return fileinfo descriptor on success, nullptr if failed,
477  *         sets last error code (check with liz_last_err())
478  */
479 struct liz_fileinfo *liz_opendir(liz_t *instance, liz_context_t *ctx, liz_inode_t inode);
480 
481 /*! \brief Read directory entries
482  * \param instance instance returned from liz_init
483  * \param fileinfo descriptor of an open directory
484  * \param offset directory entry offset
485  * \param buf buffer to be filled with readdir data
486  * \param max_entries max number of entries to be returned
487  * \param num_entries upon success set to number of entries returned in buf
488  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
489  */
490 int liz_readdir(liz_t *instance, liz_context_t *ctx, struct liz_fileinfo *fileinfo, off_t offset,
491 	                         size_t max_entries, struct liz_direntry *buf, size_t *num_entries);
492 
493 /*! \brief Destroy dir entries placed in an array
494  * \param buf buf argument to previous successful call to liz_readdir
495  * \param num_entries positive *num_entries value after respective liz_readdir() call
496  */
497 void liz_destroy_direntry(struct liz_direntry *buf, size_t num_entries);
498 
499 /*! \brief Release a directory
500  * \param instance instance returned from liz_init
501  * \param fileinfo descriptor of an open directory
502  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
503  */
504 int liz_releasedir(liz_t *instance, struct liz_fileinfo *fileinfo);
505 
506 /*! \brief Read link contents
507  * \param instance instance returned from liz_init
508  * \param ctx context returned from liz_create_context
509  * \param inode link inode
510  * \param buf filled with result on success (no trailing '\0'),
511  *        should be at least LIZARDFS_MAX_READLINK_LENGTH characters long
512  * \param size allocated buf size
513  * \return true link size on success, -1 if failed, sets last error code (check with liz_last_err())
514  */
515 int liz_readlink(liz_t *instance, liz_context_t *ctx, liz_inode_t inode, char *buf, size_t size);
516 
517 /*! \brief Get reserved file inodes and names
518  * \param instance instance returned from liz_init
519  * \param ctx context returned from liz_create_context
520  * \param offset 0-based index of the first wanted entry
521  * \param max_entries maximum number of entries to retrieve
522  * \param out_entries array entries are placed in
523  * \param num_entries number of entries placed in out_entries
524  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
525  * \post liz_free_namedinode_entries(out_entries, result) must be called
526  *       if (returned 0 && num_entries > 0) to dispose of returned entries
527  */
528 int liz_readreserved(liz_t *instance, liz_context_t *ctx, uint32_t offset, uint32_t max_entries,
529                      liz_namedinode_entry_t *out_entries, uint32_t *num_entries);
530 
531 /*! \brief Get trash file inodes and names
532  * \param instance instance returned from liz_init
533  * \param ctx context returned from liz_create_context
534  * \param offset 0-based index of the first wanted entry
535  * \param max_entries maximum number of entries to retrieve
536  * \param out_entries array entries are placed in
537  * \param num_entries number of entries placed in out_entries
538  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
539  * \post liz_free_namedinode_entry(out_entries, result) must be called
540  *       if (returned 0 && num_entries > 0) to dispose of returned entries
541  */
542 int liz_readtrash(liz_t *instance, liz_context_t *ctx, uint32_t offset, uint32_t max_entries,
543                   liz_namedinode_entry_t *out_entries, uint32_t *num_entries);
544 
545 /*! \brief Destroy named inode entries placed in an array
546  * \param entries out_entries argument to previous call to either liz_readreserved or liz_readtrash
547  * \param num_entries positive number of entries returned by the respective call
548  */
549 void liz_free_namedinode_entries(struct liz_namedinode_entry *entries, uint32_t num_entries);
550 
551 /*! \brief Create a directory
552  * \param instance instance returned from liz_init
553  * \param ctx context returned from liz_create_context
554  * \param parent parent directory inode
555  * \param name directory name
556  * \param mode directory attributes
557  * \param out_entry entry to be filled with new directory data
558  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
559  */
560 int liz_mkdir(liz_t *instance, liz_context_t *ctx, liz_inode_t parent, const char *name,
561 		mode_t mode, struct liz_entry *out_entry);
562 
563 /*! \brief Remove a directory
564  * \param instance instance returned from liz_init
565  * \param ctx context returned from liz_create_context
566  * \param parent parent directory inode
567  * \param name directory name
568  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
569  */
570 int liz_rmdir(liz_t *instance, liz_context_t *ctx, liz_inode_t parent, const char *name);
571 
572 /*! \brief Make a snapshot of a file
573  * \param instance instance returned from liz_init
574  * \param ctx context returned from liz_create_context
575  * \param inode inode of a file
576  * \param dst_parent inode of a new parent directory for a snapshot
577  * \param dst_name name of a newly created snapshot
578  * \param can_overwrite if true, snapshot creation will be able to overwrite existing files
579  * \param job_id id of makesnapshot task, can be used to cancel it, can be NULL
580  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
581  */
582 int liz_makesnapshot(liz_t *instance, liz_context_t *ctx, liz_inode_t inode, liz_inode_t dst_parent,
583 	             const char *dst_name, int can_overwrite, uint32_t *job_id);
584 
585 /*! \brief Get file goal
586  * \param instance instance returned from liz_init
587  * \param ctx context returned from liz_create_context
588  * \param inode inode of a file
589  * \param goal_name buffer to be filled with goal, must be at least LIZARDFS_MAX_GOAL_NAME long
590  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
591  */
592 int liz_getgoal(liz_t *instance, liz_context_t *ctx, liz_inode_t inode, char *goal_name);
593 
594 /*! \brief Set file goal
595  * \param instance instance returned from liz_init
596  * \param ctx context returned from liz_create_context
597  * \param inode inode of a file
598  * \param goal_name goal name to be set
599  * \param is_recursive if true, operation will apply to all subdirectories and files within them
600  * \param job_id id of setgoal task, can be used to cancel it, can be NULL
601  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
602  */
603 int liz_setgoal(liz_t *instance, liz_context_t *ctx, liz_inode_t inode, const char *goal_name,
604 	        int is_recursive);
605 
606 /*! \brief Unlink a file
607  * \param instance instance returned from liz_init
608  * \param ctx context returned from liz_create_context
609  * \param parent parent directory inode
610  * \param name file name
611  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
612  */
613 int liz_unlink(liz_t *instance, liz_context_t *ctx, liz_inode_t parent, const char *name);
614 
615 /*! \brief Restore file from trash
616  * \param instance instance returned from liz_init
617  * \param ctx context returned from liz_create_context
618  * \param inode inode of the file
619  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
620  */
621 int liz_undel(liz_t *instance, liz_context_t *ctx, liz_inode_t inode);
622 
623 /*! \brief Set file attributes
624  * \param instance instance returned from liz_init
625  * \param ctx context returned from liz_create_context
626  * \param inode inode of a file
627  * \param stbuf attributes to be set
628  * \param to_set flag which attributes should be set
629  * \param reply returned value
630  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
631  */
632 int liz_setattr(liz_t *instance, liz_context_t *ctx, liz_inode_t inode, struct stat *stbuf,
633 	        int to_set, struct liz_attr_reply *reply);
634 
635 /*! \brief Synchronize file data
636  * \param instance instance returned from liz_init
637  * \param ctx context returned from liz_create_context
638  * \param fileinfo descriptor of an open file
639  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
640  */
641 int liz_fsync(liz_t *instance, liz_context_t *ctx, struct liz_fileinfo *fileinfo);
642 
643 /*! \brief Rename a file
644  * \param instance instance returned from liz_init
645  * \param ctx context returned from liz_create_context
646  * \param parent current parent of a file to be moved
647  * \param name name of a file to be moved
648  * \param new_parent inode of a new directory
649  * \param new_name new name of a file to be moved
650  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
651  */
652 int liz_rename(liz_t *instance, liz_context_t *ctx, liz_inode_t parent, const char *name,
653 	       liz_inode_t new_parent, const char *new_name);
654 
655 /*! \brief Retrieve file system statistics
656  * \param instance instance returned from liz_init
657  * \param buf structure to be filled with file system statistics
658  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
659  */
660 int liz_statfs(liz_t *instance, liz_stat_t *buf);
661 
662 /*! \brief Set extended attribute of a file
663  * \param instance instance returned from liz_init
664  * \param ctx context returned from liz_create_context
665  * \param ino inode of a file
666  * \param name attribute name
667  * \param value attribute value
668  * \param size size of attribute value
669  * \param mode one of enum liz_setxattr_mode values
670  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
671  */
672 int liz_setxattr(liz_t *instance, liz_context_t *ctx, liz_inode_t ino, const char *name,
673 	         const uint8_t *value, size_t size, enum liz_setxattr_mode mode);
674 
675 /*! \brief Get extended attribute of a file
676  * \param instance instance returned from liz_init
677  * \param ctx context returned from liz_create_context
678  * \param ino inode of a file
679  * \param name attribute name
680  * \param size size of the provided buffer
681  * \param out_size filled with actual size of xattr value
682  * \param buf buffer to be filled with xattr value
683  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
684  */
685 int liz_getxattr(liz_t *instance, liz_context_t *ctx, liz_inode_t ino, const char *name,
686 	         size_t size, size_t *out_size, uint8_t *buf);
687 
688 /*! \brief Get extended attributes list of a file
689  * \param instance instance returned from liz_init
690  * \param ctx context returned from liz_create_context
691  * \param ino inode of a file
692  * \param size size of the provided buffer
693  * \param buf buffer to be filled with listed attributes
694  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
695  */
696 int liz_listxattr(liz_t *instance, liz_context_t *ctx, liz_inode_t ino, size_t size,
697 	          size_t *out_size, char *buf);
698 
699 /*! \brief Remove extended attribute from a file
700  * \param instance instance returned from liz_init
701  * \param ctx context returned from liz_create_context
702  * \param ino inode of a file
703  * \param name attribute name
704  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
705  */
706 int liz_removexattr(liz_t *instance, liz_context_t *ctx, liz_inode_t ino, const char *name);
707 
708 /*!
709  * \brief Create acl
710  * \return acl entry
711  * \post free memory with liz_destroy_acl call
712  */
713 liz_acl_t *liz_create_acl();
714 
715 /*!
716  * \brief Destroy acl
717  * \param acl access control list
718  */
719 void liz_destroy_acl(liz_acl_t *acl);
720 
721 /*!
722  * \brief Print acl in human readable format
723  * \param acl access control list
724  * \param buf buffer to be filled with acl representation
725  * \param size buffer size
726  * \param reply_size size needed to store acl representation
727  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
728  */
729 int liz_print_acl(liz_acl_t *acl, char *buf, size_t size, size_t *reply_size);
730 
731 /*!
732  * \brief Add access control entry to acl
733  * \param acl access control list
734  * \param ace prepared acl entry
735  */
736 void liz_add_acl_entry(liz_acl_t *acl, const liz_acl_ace_t *ace);
737 
738 /*!
739  * \brief Get nth acl entry
740  * \param acl access control list
741  * \param n entry index
742  * \param ace entry to be filled with data
743  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
744  */
745 int liz_get_acl_entry(const liz_acl_t *acl, int n, liz_acl_ace_t *ace);
746 
747 /*!
748  * \brief Get number of acl entries
749  * \param acl access control list
750  * \return number of entries
751  */
752 size_t liz_get_acl_size(const liz_acl_t *acl);
753 
754 /*!
755  * \brief Set acl for a file
756  * \param instance instance returned from liz_init
757  * \param ctx context returned from liz_create_context
758  * \param ino target inode
759  * \param type acl type (access, default)
760  * \param acl acl to be set
761  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
762  */
763 int liz_setacl(liz_t *instance, liz_context_t *ctx, liz_inode_t ino,
764 	       const liz_acl_t *acl);
765 
766 /*!
767  * \brief Get acl from a file
768  * \param instance instance returned from liz_init
769  * \param ctx context returned from liz_create_context
770  * \param ino target inode
771  * \param type acl type (access, default)
772  * \param acl acl pointer to be filled with acl
773  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
774  */
775 int liz_getacl(liz_t *instance, liz_context_t *ctx, liz_inode_t ino,
776 	       liz_acl_t **acl);
777 
778 /*! \brief Gather chunks information for a file
779  * \param instance instance returned from liz_init
780  * \param ctx context returned from liz_create_context
781  * \param inode inode of a file
782  * \param chunk_index index of first chunk to return
783  * \param buffer preallocated buffer for chunk info
784  * \param buffer_size size of preallocated buffer in number of elements
785  * \param reply_size number of liz_chunk_info_t structures returned from master
786  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
787  * \post retrieved chunks information should be freed with liz_destroy_chunks_info call
788  */
789 int liz_get_chunks_info(liz_t *instance, liz_context_t *ctx, liz_inode_t inode,
790 	                    uint32_t chunk_index, liz_chunk_info_t *buffer, uint32_t buffer_size,
791 	                    uint32_t *reply_size);
792 
793 /*! \brief Free data allocated in liz_get_chunks_info
794  * \param buffer buffer used in a successful liz_get_chunks_info call
795  */
796 void liz_destroy_chunks_info(liz_chunk_info_t *buffer);
797 
798 /*! \brief Gather information on chunkservers present in the cluster
799  * \param instance instance returned from liz_init
800  * \param servers buffer to be filled with server info
801  * \param size buffer size in the number of elements
802  * \param reply_size number of server entries returned from master
803  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
804  * \post retrieved chunkservers information should be freed with liz_destroy_chunkservers_info call
805  */
806 int liz_get_chunkservers_info(liz_t *instance, liz_chunkserver_info_t *servers, uint32_t size,
807 	                 uint32_t *reply_size);
808 
809 /*! \brief Free data allocated in liz_get_chunkservers_info
810  * \param buffer buffer used in a successful liz_get_chunkservers_info call
811  */
812 void liz_destroy_chunkservers_info(liz_chunkserver_info_t *buffer);
813 
814 /*! \brief Put a lock on a file (semantics based on POSIX setlk)
815  * \param instance instance returned from liz_init
816  * \param ctx context returned from liz_create_context
817  * \param fileinfo descriptor of an open file
818  * \param lock lock information
819  * \param handler function used to register lock interrupt data, can be NULL
820  * \param priv private user data passed to handler
821  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
822  * \post interrupt data registered by handler can be later passed to liz_setlk_interrupt
823  *       in order to cancel a lock request
824  */
825 int liz_setlk(liz_t *instance, liz_context_t *ctx, liz_fileinfo_t *fileinfo,
826 	      const liz_lock_info_t *lock, liz_lock_register_interrupt_t handler, void *priv);
827 
828 /*! \brief Get lock information from a file (semantics based on POSIX getlk)
829  * \param instance instance returned from liz_init
830  * \param ctx context returned from liz_create_context
831  * \param fileinfo descriptor of an open file
832  * \param lock lock buffer to be filled with lock information
833  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
834  */
835 int liz_getlk(liz_t *instance, liz_context_t *ctx, liz_fileinfo_t *fileinfo, liz_lock_info_t *lock);
836 
837 /*! \brief Cancel a lock request
838  * \param instance instance returned from liz_init
839  * \param interrupt_info interrupt data saved by a function passed to setlk
840  * \return 0 on success, -1 if failed, sets last error code (check with liz_last_err())
841  */
842 int liz_setlk_interrupt(liz_t *instance, const liz_lock_interrupt_info_t *interrupt_info);
843 #ifdef __cplusplus
844 } // extern "C"
845 #endif
846 
847 #endif
848