2 demonstration of checking if a file is offline using DMAPI, with
3 shortcut tricks using st_atime and st_blocks
6 gcc -o isoffline isoffline.c -ldmapi
8 Andrew Tridgell (tridgell@au1.ibm.com) July 2007
21 /* optimisation tunables - used to avoid the DMAPI slow path */
22 #define FILE_IS_ONLINE_RATIO 0.5
23 #define FILE_IS_ONLINE_ATIME 60
27 see if a file is offline
29 return -1 on failure. Set *offline to true/false according to
32 static int is_offline(char *fname, time_t now, bool *offline)
39 dm_attrname_t dmAttrName;
40 /* keep some state between calls, to save on session creation calls */
41 static struct dmapi_state {
48 /* create a new session if needed */
49 if (dm_create_session(DM_NO_SESSION, "samba", &state.sid) != 0) {
54 /* try shortcut methods first */
55 if (stat(fname, &st) != 0) {
59 /* if the file has more than FILE_IS_ONLINE_RATIO of blocks available,
60 then assume its not offline (it may not be 100%, as it could be sparse) */
61 if (512 * (off_t)st.st_blocks > st.st_size * FILE_IS_ONLINE_RATIO) {
66 /* go the slow DMAPI route */
67 if (dm_path_to_handle(fname, &handle, &handle_len) != 0) {
71 memset(&dmAttrName, 0, sizeof(dmAttrName));
72 strcpy((char *)&dmAttrName.an_chars[0], "IBMObj");
74 ret = dm_get_dmattr(state.sid, handle, handle_len,
75 DM_NO_TOKEN, &dmAttrName, 0, NULL, &rlen);
77 /* its offline if the IBMObj attribute exists */
78 *offline = (ret == 0 || (ret == -1 && errno == E2BIG));
80 dm_handle_free(handle, handle_len);
85 int main(int argc, char *argv[])
88 time_t now = time(NULL);
91 printf("isoffline <fname...>\n");
94 for (i=1;i<argc;i++) {
96 if (is_offline(argv[i], now, &offline) == -1) {
100 printf("%s\t%s\n", offline?"offline":"online ", argv[i]);