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
20 /* optimisation tunables - used to avoid the DMAPI slow path */
21 #define FILE_IS_ONLINE_RATIO 0.5
22 #define FILE_IS_ONLINE_ATIME 60
26 see if a file is offline
28 return -1 on failure. Set *offline to true/false according to
31 static int is_offline(char *fname, time_t now, bool *offline)
38 dm_attrname_t dmAttrName;
39 /* keep some state between calls, to save on session creation calls */
40 static struct dmapi_state {
47 /* create a new session if needed */
48 if (dm_create_session(DM_NO_SESSION, "samba", &state.sid) != 0) {
53 /* try shortcut methods first */
54 if (stat(fname, &st) != 0) {
58 /* if the file has more than FILE_IS_ONLINE_RATIO of blocks available,
59 then assume its not offline (it may not be 100%, as it could be sparse) */
60 if (512 * (off_t)st.st_blocks > st.st_size * FILE_IS_ONLINE_RATIO) {
65 /* go the slow DMAPI route */
66 if (dm_path_to_handle(fname, &handle, &handle_len) != 0) {
70 memset(&dmAttrName, 0, sizeof(dmAttrName));
71 strcpy((char *)&dmAttrName.an_chars[0], "IBMObj");
73 ret = dm_get_dmattr(state.sid, handle, handle_len,
74 DM_NO_TOKEN, &dmAttrName, 0, NULL, &rlen);
76 /* its offline if the IBMObj attribute exists */
77 *offline = (ret == 0 || (ret == -1 && errno == E2BIG));
79 dm_handle_free(handle, handle_len);
84 int main(int argc, char *argv[])
87 time_t now = time(NULL);
90 printf("isoffline <fname...>\n");
93 for (i=1;i<argc;i++) {
95 if (is_offline(argv[i], now, &offline) == -1) {
99 printf("%s\t%s\n", offline?"offline":"online ", argv[i]);