int main(int argc, char **argv) { char *varstr; int rc; int varStatus; char *szSessionInfo = "dm_test session info"; dm_eventset_t events; DMOPT_PARSE(argc, argv); DMLOG_START(); DMEV_ZERO(events); DMEV_SET(DM_EVENT_MOUNT, events); /* CANNOT DO ANYTHING WITHOUT SUCCESSFUL INITIALIZATION!!! */ if ((rc = dm_init_service(&varstr)) != 0) { DMLOG_PRINT(DMLVL_ERR, "dm_init_service failed! (rc = %d, errno = %d)\n", rc, errno); DM_EXIT(); } else if ((rc = dm_create_session(DM_NO_SESSION, szSessionInfo, &sid)) == -1) { DMLOG_PRINT(DMLVL_ERR, "dm_create_session failed! (rc = %d, errno = %d)\n", rc, errno); DM_EXIT(); } else if ((rc = dm_set_disp(sid, DM_GLOBAL_HANP, DM_GLOBAL_HLEN, DM_NO_TOKEN, &events, DM_EVENT_MAX)) == -1) { DMLOG_PRINT(DMLVL_ERR, "dm_set_disp failed! (rc = %d, errno = %d)\n", rc, errno); dm_destroy_session(sid); DM_EXIT(); } else if ((rc = pthread_create(&tid, NULL, Thread, NULL)) != 0) { DMLOG_PRINT(DMLVL_ERR, "pthread_create failed! (rc = %d, errno = %d)\n", rc, errno); dm_destroy_session(sid); DM_EXIT(); } else if ((rc = dmimpl_mount(&mountPt, &deviceNm)) == -1) { DMLOG_PRINT(DMLVL_ERR, "dmimpl_mount failed! (rc = %d, errno = %d)\n", rc, errno); dm_destroy_session(sid); DM_EXIT(); } else { sprintf(DummyFile, "%s/%s", mountPt, DUMMY_FILE); sprintf(DummyFile2, "%s/%s", mountPt, DUMMY_FILE2); sprintf(DummySubdir, "%s/%s", mountPt, DUMMY_SUBDIR); sprintf(DummySubdir2, "%s/%s", mountPt, DUMMY_SUBDIR2); sprintf(DummyLink, "%s/%s", mountPt, DUMMY_LINK); remove(DummyFile); remove(DummyFile2); unlink(DummyLink); rmdir(DummySubdir); rmdir(DummySubdir2); } DMLOG_PRINT(DMLVL_DEBUG, "Starting DMAPI synchronous namespace event tests\n") ; /* * TEST : mkdir - DM_RESP_CONTINUE * EXPECTED: DM_EVENT_CREATE */ if (DMVAR_EXEC(DIR_SYNC_NAMESP_EVENT_BASE + 1)) { dm_ino_t ino; /* Variation set up */ eventExpected = DM_EVENT_CREATE; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; /* Variation */ EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "mkdir(%s)\n", DummySubdir); rc = mkdir(DummySubdir, DUMMY_DIR_RW_MODE); DMLOG_PRINT(DMLVL_DEBUG, "mkdir(%s) returned %d\n", DummySubdir, rc); if ((varStatus = DMVAR_CHKPASSEXP(0, rc, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Parent handle NOT root! (%lld vs %d)\n", ino, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_SUBDIR) != 0) { DMLOG_PRINT(DMLVL_ERR, "Entry name NOT correct! (%s vs %s)\n", name1, DUMMY_SUBDIR); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ EVENT_DELIVERY_DELAY; rc = rmdir(DummySubdir); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to clean up variation! (errno = %d)\n", errno); } } /* * TEST : mkdir - DM_RESP_ABORT * EXPECTED: DM_EVENT_CREATE */ if (DMVAR_EXEC(DIR_SYNC_NAMESP_EVENT_BASE + 2)) { dm_ino_t ino; /* Variation set up */ eventExpected = DM_EVENT_CREATE; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_ABORT; /* Variation */ EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "mkdir(%s)\n", DummySubdir); rc = mkdir(DummySubdir, DUMMY_DIR_RW_MODE); DMLOG_PRINT(DMLVL_DEBUG, "mkdir(%s) returned %d\n", DummySubdir, rc); if ((varStatus = DMVAR_CHKFAILEXP(-1, rc, ABORT_ERRNO, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Parent handle NOT root! (%lld vs %d)\n", ino, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_SUBDIR) != 0) { DMLOG_PRINT(DMLVL_ERR, "Entry name NOT correct! (%s vs %s)\n", name1, DUMMY_SUBDIR); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ } /* * TEST : rmdir - DM_RESP_CONTINUE * EXPECTED: DM_EVENT_REMOVE */ if (DMVAR_EXEC(DIR_SYNC_NAMESP_EVENT_BASE + 3)) { dm_ino_t ino; /* Variation set up */ eventExpected = DM_EVENT_REMOVE; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; rc = mkdir(DummySubdir, DUMMY_DIR_RW_MODE); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); DMVAR_SKIP(); } else { /* Variation */ EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "rmdir(%s)\n", DummySubdir); rc = rmdir(DummySubdir); DMLOG_PRINT(DMLVL_DEBUG, "rmdir(%s) returned %d\n", DummySubdir, rc); if ((varStatus = DMVAR_CHKPASSEXP(0, rc, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Parent handle NOT root! (%lld vs %d)\n", ino, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_SUBDIR) != 0) { DMLOG_PRINT(DMLVL_ERR, "Entry name NOT correct! (%s vs %s)\n", name1, DUMMY_SUBDIR); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ } } /* * TEST : rmdir - DM_RESP_ABORT * EXPECTED: DM_EVENT_REMOVE */ if (DMVAR_EXEC(DIR_SYNC_NAMESP_EVENT_BASE + 4)) { dm_ino_t ino; /* Variation set up */ eventExpected = DM_EVENT_REMOVE; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; rc = mkdir(DummySubdir, DUMMY_DIR_RW_MODE); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); DMVAR_SKIP(); } else { /* Variation */ eventResponse = DM_RESP_ABORT; EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "rmdir(%s)\n", DummySubdir); rc = rmdir(DummySubdir); DMLOG_PRINT(DMLVL_DEBUG, "rmdir(%s) returned %d\n", DummySubdir, rc); if ((varStatus = DMVAR_CHKFAILEXP(-1, rc, ABORT_ERRNO, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Parent handle NOT root! (%lld vs %d)\n", ino, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_SUBDIR) != 0) { DMLOG_PRINT(DMLVL_ERR, "Entry name NOT correct! (%s vs %s)\n", name1, DUMMY_SUBDIR); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; rc = rmdir(DummySubdir); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to clean up variation! (errno = %d)\n", errno); } } } /* * TEST : mv - DM_RESP_CONTINUE * EXPECTED: DM_EVENT_RENAME */ if (DMVAR_EXEC(DIR_SYNC_NAMESP_EVENT_BASE + 5)) { dm_ino_t ino1, ino2; /* Variation set up */ eventExpected = DM_EVENT_RENAME; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; sprintf(command, "mv %s %s", DummySubdir, DummySubdir2); EVENT_DELIVERY_DELAY; rc = mkdir(DummySubdir, DUMMY_DIR_RW_MODE); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); DMVAR_SKIP(); } else { /* Variation */ EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "system(mv %s %s)\n", DummySubdir, DummySubdir2); rc = system(command); DMLOG_PRINT(DMLVL_DEBUG, "system(mv %s %s) returned %d\n", DummySubdir, DummySubdir2, rc); if ((varStatus = DMVAR_CHKPASSEXP(0, rc, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino1); rc |= dm_handle_to_ino(hanp2, hlen2, &ino2); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino1 != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Old parent handle NOT root! (%lld vs %d)\n", ino1, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (ino2 != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "New parent handle NOT root! (%lld vs %d)\n", ino2, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (dm_handle_cmp(hanp1, hlen1, hanp2, hlen2) != 0) { DMLOG_PRINT(DMLVL_ERR, "Old parent handle NOT equal to new parent handle!\n"); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_SUBDIR) != 0) { DMLOG_PRINT(DMLVL_ERR, "Old entry name NOT correct! (%s vs %s)\n", name1, DUMMY_SUBDIR); varStatus = DMSTAT_FAIL; } else if (strcmp(name2, DUMMY_SUBDIR2) != 0) { DMLOG_PRINT(DMLVL_ERR, "New entry name NOT correct! (%s vs %s)\n", name2, DUMMY_SUBDIR2); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ EVENT_DELIVERY_DELAY; rc = rmdir(DummySubdir2); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to clean up variation! (errno = %d)\n", errno); } } } /* * TEST : mv - DM_RESP_ABORT * EXPECTED: DM_EVENT_RENAME */ if (DMVAR_EXEC(DIR_SYNC_NAMESP_EVENT_BASE + 6)) { dm_ino_t ino1, ino2; /* Variation set up */ eventExpected = DM_EVENT_RENAME; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; sprintf(command, "mv %s %s", DummySubdir, DummySubdir2); EVENT_DELIVERY_DELAY; rc = mkdir(DummySubdir, DUMMY_DIR_RW_MODE); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); DMVAR_SKIP(); } else { /* Variation */ eventResponse = DM_RESP_ABORT; EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "system(mv %s %s)\n", DummySubdir, DummySubdir2); rc = system(command); DMLOG_PRINT(DMLVL_DEBUG, "system(mv %s %s) returned %d\n", DummySubdir, DummySubdir2, rc); if ((varStatus = (rc == 0 ? DMSTAT_FAIL : DMSTAT_PASS)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino1); rc |= dm_handle_to_ino(hanp2, hlen2, &ino2); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino1 != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Old parent handle NOT root! (%lld vs %d)\n", ino1, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (ino2 != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "New parent handle NOT root! (%lld vs %d)\n", ino2, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (dm_handle_cmp(hanp1, hlen1, hanp2, hlen2) != 0) { DMLOG_PRINT(DMLVL_ERR, "Old parent handle NOT equal to new parent handle!\n"); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_SUBDIR) != 0) { DMLOG_PRINT(DMLVL_ERR, "Old entry name NOT correct! (%s vs %s)\n", name1, DUMMY_SUBDIR); varStatus = DMSTAT_FAIL; } else if (strcmp(name2, DUMMY_SUBDIR2) != 0) { DMLOG_PRINT(DMLVL_ERR, "New entry name NOT correct! (%s vs %s)\n", name2, DUMMY_SUBDIR2); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; rc = rmdir(DummySubdir); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to clean up variation! (errno = %d)\n", errno); } } } /* * TEST : symlink - DM_RESP_CONTINUE * EXPECTED: DM_EVENT_SYMLINK */ if (DMVAR_EXEC(DIR_SYNC_NAMESP_EVENT_BASE + 7)) { dm_ino_t ino; /* Variation set up */ eventExpected = DM_EVENT_SYMLINK; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; rc = mkdir(DummySubdir, DUMMY_DIR_RW_MODE); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); DMVAR_SKIP(); } else { /* Variation */ EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "symlink(%s, %s)\n", DummySubdir, DummySubdir2); rc = symlink(DummySubdir, DummySubdir2); DMLOG_PRINT(DMLVL_DEBUG, "symlink(%s, %s) returned %d\n", DummySubdir, DummySubdir2, rc); if ((varStatus = DMVAR_CHKPASSEXP(0, rc, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Parent handle NOT root! (%lld vs %d)\n", ino, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_SUBDIR2) != 0) { DMLOG_PRINT(DMLVL_ERR, "Symlink entry name NOT correct! (%s vs %s)\n", name1, DUMMY_SUBDIR2); varStatus = DMSTAT_FAIL; } else if (strcmp(name2, DummySubdir) != 0) { DMLOG_PRINT(DMLVL_ERR, "Symlink contents NOT correct! (%s vs %s)\n", name2, DummySubdir); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ EVENT_DELIVERY_DELAY; rc = unlink(DummySubdir2); rc |= rmdir(DummySubdir); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to clean up variation! (errno = %d)\n", errno); } } } /* * TEST : symlink - DM_RESP_ABORT * EXPECTED: DM_EVENT_SYMLINK */ if (DMVAR_EXEC(DIR_SYNC_NAMESP_EVENT_BASE + 8)) { dm_ino_t ino; /* Variation set up */ eventExpected = DM_EVENT_SYMLINK; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; rc = mkdir(DummySubdir, DUMMY_DIR_RW_MODE); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); DMVAR_SKIP(); } else { /* Variation */ eventResponse = DM_RESP_ABORT; EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "symlink(%s, %s)\n", DummySubdir, DummySubdir2); rc = symlink(DummySubdir, DummySubdir2); DMLOG_PRINT(DMLVL_DEBUG, "symlink(%s, %s) returned %d\n", DummySubdir, DummySubdir2, rc); EVENT_DELIVERY_DELAY; if ((varStatus = DMVAR_CHKFAILEXP(-1, rc, ABORT_ERRNO, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Parent handle NOT root! (%lld vs %d)\n", ino, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_SUBDIR2) != 0) { DMLOG_PRINT(DMLVL_ERR, "Symlink entry name NOT correct! (%s vs %s)\n", name1, DUMMY_SUBDIR2); varStatus = DMSTAT_FAIL; } else if (strcmp(name2, DummySubdir) != 0) { DMLOG_PRINT(DMLVL_ERR, "Symlink contents NOT correct! (%s vs %s)\n", name2, DummySubdir); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; rc = rmdir(DummySubdir); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to clean up variation! (errno = %d)\n", errno); } } } /* * TEST : link - DM_RESP_CONTINUE * EXPECTED: DM_EVENT_LINK */ if (DMVAR_EXEC(DIR_SYNC_NAMESP_EVENT_BASE + 9)) { #ifdef DIRECTORY_LINKS dm_ino_t ino1, ino2, ino3; void *hanp; size_t hlen; /* Variation set up */ eventExpected = DM_EVENT_LINK; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; if ((rc = mkdir(DummySubdir, DUMMY_DIR_RW_MODE)) == -1) { /* No clean up */ } else if ((rc = dm_path_to_handle(DummySubdir, &hanp, &hlen)) == -1) { rmdir(DummySubdir); } if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); DMVAR_SKIP(); } else { /* Variation */ EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "link(%s, %s)\n", DummySubdir, DummyLink); rc = link(DummySubdir, DummyLink); DMLOG_PRINT(DMLVL_DEBUG, "link(%s, %s) returned %d\n", DummySubdir, DummyLink, rc); if ((varStatus = DMVAR_CHKPASSEXP(0, rc, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino1); rc |= dm_handle_to_ino(hanp2, hlen2, &ino2); rc |= dm_handle_to_ino(hanp, hlen, &ino3); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino1 != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Parent handle NOT root! (%lld vs %d)\n", ino1, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (ino2 != ino3) { DMLOG_PRINT(DMLVL_ERR, "Source link handle NOT correct! (%lld vs %lld)\n", ino2, ino3); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_LINK) != 0) { DMLOG_PRINT(DMLVL_ERR, "Target entry name NOT correct! (%s vs %s)\n", name1, DUMMY_LINK); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ EVENT_DELIVERY_DELAY; rc = rmdir(DummySubdir); rc |= unlink(DummyLink); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to clean up variation! (errno = %d)\n", errno); } dm_handle_free(hanp, hlen); } #else DMLOG_PRINT(DMLVL_WARN, "Test case not built with DIRECTORY_LINKS defined\n"); DMVAR_SKIP(); #endif } /* * TEST : link - DM_RESP_ABORT * EXPECTED: DM_EVENT_LINK */ if (DMVAR_EXEC(DIR_SYNC_NAMESP_EVENT_BASE + 10)) { #ifdef DIRECTORY_LINKS dm_ino_t ino1, ino2, ino3; void *hanp; size_t hlen; /* Variation set up */ eventExpected = DM_EVENT_LINK; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; if ((rc = mkdir(DummySubdir, DUMMY_DIR_RW_MODE)) == -1) { /* No clean up */ } else if ((rc = dm_path_to_handle(DummySubdir, &hanp, &hlen)) == -1) { rmdir(DummySubdir); } if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); DMVAR_SKIP(); } else { /* Variation */ eventResponse = DM_RESP_ABORT; EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "link(%s, %s)\n", DummySubdir, DummyLink); rc = link(DummySubdir, DummyLink); DMLOG_PRINT(DMLVL_DEBUG, "link(%s, %s) returned %d\n", DummySubdir, DummyLink, rc); if ((varStatus = DMVAR_CHKFAILEXP(-1, rc, ABORT_ERRNO, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino1); rc |= dm_handle_to_ino(hanp2, hlen2, &ino2); rc |= dm_handle_to_ino(hanp, hlen, &ino3); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino1 != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Parent handle NOT root! (%lld vs %d)\n", ino1, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (ino2 != ino3) { DMLOG_PRINT(DMLVL_ERR, "Source link handle NOT correct! (%lld vs %lld)\n", ino2, ino3); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_LINK) != 0) { DMLOG_PRINT(DMLVL_ERR, "Target entry name NOT correct! (%s vs %s)\n", name1, DUMMY_LINK); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; rc = rmdir(DummySubdir); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to clean up variation! (errno = %d)\n", errno); } dm_handle_free(hanp, hlen); } #else DMLOG_PRINT(DMLVL_WARN, "Test case not built with DIRECTORY_LINKS defined\n"); DMVAR_SKIP(); #endif } /* * TEST : open * EXPECTED: DM_EVENT_CREATE, DM_RESP_CONTINUE */ if (DMVAR_EXEC(FILE_SYNC_NAMESP_EVENT_BASE + 1)) { int fd; dm_ino_t ino; /* Variation set up */ eventExpected = DM_EVENT_CREATE; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; /* Variation */ EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "open(%s)\n", DummyFile); fd = open(DummyFile, O_RDWR | O_CREAT, DUMMY_FILE_RW_MODE); DMLOG_PRINT(DMLVL_DEBUG, "open(%s) returned %d\n", DummyFile, fd); rc = (fd == -1) ? -1 : 0; if ((varStatus = DMVAR_CHKPASSEXP(0, rc, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Parent handle NOT root! (%lld vs %d)\n", ino, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_FILE) != 0) { DMLOG_PRINT(DMLVL_ERR, "Entry name NOT correct! (%s %s)\n", name1, DUMMY_SUBDIR); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ EVENT_DELIVERY_DELAY; rc = close(fd); rc |= remove(DummyFile); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to clean up variation! (errno = %d)\n", errno); } } /* * TEST : open * EXPECTED: DM_EVENT_CREATE, DM_RESP_ABORT */ if (DMVAR_EXEC(FILE_SYNC_NAMESP_EVENT_BASE + 2)) { dm_ino_t ino; int fd; /* Variation set up */ eventExpected = DM_EVENT_CREATE; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_ABORT; /* Variation */ EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "open(%s)\n", DummyFile); fd = open(DummyFile, O_RDWR | O_CREAT, DUMMY_FILE_RW_MODE); DMLOG_PRINT(DMLVL_DEBUG, "open(%s) returned %d\n", DummyFile, fd); if ((varStatus = DMVAR_CHKFAILEXP(-1, fd, ABORT_ERRNO, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Parent handle NOT root! (%lld vs %d)\n", ino, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_FILE) != 0) { DMLOG_PRINT(DMLVL_ERR, "Entry name NOT correct! (%s vs %s)\n", name1, DUMMY_FILE); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ } /* * TEST : remove * EXPECTED: DM_EVENT_REMOVE, DM_RESP_CONTINUE */ if (DMVAR_EXEC(FILE_SYNC_NAMESP_EVENT_BASE + 3)) { dm_ino_t ino; int fd; /* Variation set up */ eventExpected = DM_EVENT_REMOVE; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; if ((fd = open(DummyFile, O_RDWR | O_CREAT, DUMMY_FILE_RW_MODE)) != -1) { rc = close(fd); } if (fd == -1 || rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); DMVAR_SKIP(); } else { /* Variation */ EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "remove(%s)\n", DummyFile); rc = remove(DummyFile); DMLOG_PRINT(DMLVL_DEBUG, "remove(%s) returned %d\n", DummyFile, rc); if ((varStatus = DMVAR_CHKPASSEXP(0, rc, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Parent handle NOT root! (%lld vs %d)\n", ino, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_FILE) != 0) { DMLOG_PRINT(DMLVL_ERR, "Entry name NOT correct! (%s vs %s)\n", name1, DUMMY_FILE); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ } } /* * TEST : remove * EXPECTED: DM_EVENT_REMOVE, DM_RESP_ABORT */ if (DMVAR_EXEC(FILE_SYNC_NAMESP_EVENT_BASE + 4)) { dm_ino_t ino; int fd; /* Variation set up */ eventExpected = DM_EVENT_REMOVE; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; if ((fd = open(DummyFile, O_RDWR | O_CREAT, DUMMY_FILE_RW_MODE)) != -1) { rc = close(fd); } if (fd == -1 || rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); DMVAR_SKIP(); } else { /* Variation */ eventResponse = DM_RESP_ABORT; EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "remove(%s)\n", DummyFile); rc = remove(DummyFile); DMLOG_PRINT(DMLVL_DEBUG, "remove(%s) returned %d\n", DummyFile, rc); if ((varStatus = DMVAR_CHKFAILEXP(-1, rc, ABORT_ERRNO, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Parent handle NOT root! (%lld vs %d)\n", ino, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_FILE) != 0) { DMLOG_PRINT(DMLVL_ERR, "Entry name NOT correct! (%s vs %s)\n", name1, DUMMY_FILE); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; rc = remove(DummyFile); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to clean up variation! (errno = %d)\n", errno); } } } /* * TEST : mv * EXPECTED: DM_EVENT_RENAME, DM_RESP_CONTINUE */ if (DMVAR_EXEC(FILE_SYNC_NAMESP_EVENT_BASE + 5)) { dm_ino_t ino1, ino2; int fd; /* Variation set up */ eventExpected = DM_EVENT_RENAME; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; sprintf(command, "mv %s %s", DummyFile, DummyFile2); EVENT_DELIVERY_DELAY; if ((fd = open(DummyFile, O_RDWR | O_CREAT, DUMMY_FILE_RW_MODE)) != -1) { rc = close(fd); } if (fd == -1 || rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); DMVAR_SKIP(); } else { /* Variation */ EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "system(mv %s %s)\n", DummyFile, DummyFile2); rc = system(command); DMLOG_PRINT(DMLVL_DEBUG, "system(mv %s %s) returned %d\n", DummyFile, DummyFile2, rc); if ((varStatus = DMVAR_CHKPASSEXP(0, rc, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino1); rc |= dm_handle_to_ino(hanp2, hlen2, &ino2); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino1 != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Old parent handle NOT root! (%lld vs %d)\n", ino1, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (ino2 != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "New parent handle NOT root! (%lld vs %d)\n", ino2, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (dm_handle_cmp(hanp1, hlen1, hanp2, hlen2) != 0) { DMLOG_PRINT(DMLVL_ERR, "Old parent handle NOT equal to new parent handle!\n"); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_FILE) != 0) { DMLOG_PRINT(DMLVL_ERR, "Old entry name NOT correct! (%s vs %s)\n", name1, DUMMY_FILE); varStatus = DMSTAT_FAIL; } else if (strcmp(name2, DUMMY_FILE2) != 0) { DMLOG_PRINT(DMLVL_ERR, "New entry name NOT correct! (%s vs %s)\n", name2, DUMMY_FILE2); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ EVENT_DELIVERY_DELAY; rc = remove(DummyFile2); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); } } } /* * TEST : mv * EXPECTED: DM_EVENT_RENAME, DM_RESP_ABORT */ if (DMVAR_EXEC(FILE_SYNC_NAMESP_EVENT_BASE + 6)) { dm_ino_t ino1, ino2; int fd; /* Variation set up */ eventExpected = DM_EVENT_RENAME; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; sprintf(command, "mv %s %s", DummyFile, DummyFile2); EVENT_DELIVERY_DELAY; if ((fd = open(DummyFile, O_RDWR | O_CREAT, DUMMY_FILE_RW_MODE)) != -1) { rc = close(fd); } if (fd == -1 || rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); DMVAR_SKIP(); } else { /* Variation */ eventResponse = DM_RESP_ABORT; EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "system(mv %s %s)\n", DummyFile, DummyFile2); rc = system(command); DMLOG_PRINT(DMLVL_DEBUG, "system(mv %s %s) returned %d\n", DummyFile, DummyFile2, rc); if ((varStatus = (rc == 0 ? DMSTAT_FAIL : DMSTAT_PASS)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino1); rc |= dm_handle_to_ino(hanp2, hlen2, &ino2); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino1 != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Old parent handle NOT root! (%lld vs %d)\n", ino1, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (ino2 != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "New parent handle NOT root! (%lld vs %d)\n", ino2, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (dm_handle_cmp(hanp1, hlen1, hanp2, hlen2) != 0) { DMLOG_PRINT(DMLVL_ERR, "Old parent handle NOT equal to new parent handle!\n"); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_FILE) != 0) { DMLOG_PRINT(DMLVL_ERR, "Old entry name NOT correct! (%s vs %s)\n", name1, DUMMY_FILE); varStatus = DMSTAT_FAIL; } else if (strcmp(name2, DUMMY_FILE2) != 0) { DMLOG_PRINT(DMLVL_ERR, "New entry name NOT correct! (%s vs %s)\n", name2, DUMMY_FILE2); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; rc = remove(DummyFile); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to clean up variation! (errno = %d)\n", errno); } } } /* * TEST : symlink * EXPECTED: DM_EVENT_SYMLINK, DM_RESP_CONTINUE */ if (DMVAR_EXEC(FILE_SYNC_NAMESP_EVENT_BASE + 7)) { dm_ino_t ino; int fd; /* Variation set up */ eventExpected = DM_EVENT_SYMLINK; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; if ((fd = open(DummyFile, O_RDWR | O_CREAT, DUMMY_FILE_RW_MODE)) != -1) { rc = close(fd); } if (fd == -1 || rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); DMVAR_SKIP(); } else { /* Variation */ EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "symlink(%s, %s)\n", DummyFile, DummyLink); rc = symlink(DummyFile, DummyLink); DMLOG_PRINT(DMLVL_DEBUG, "symlink(%s, %s) returned %d\n", DummyFile, DummyLink, rc); if ((varStatus = DMVAR_CHKPASSEXP(0, rc, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Parent handle NOT root! (%lld vs %d)\n", ino, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_LINK) != 0) { DMLOG_PRINT(DMLVL_ERR, "Symlink entry name NOT correct! (%s vs %s)\n", name1, DUMMY_LINK); varStatus = DMSTAT_FAIL; } else if (strcmp(name2, DummyFile) != 0) { DMLOG_PRINT(DMLVL_ERR, "Symlink contents NOT correct! (%s vs %s)\n", name2, DummyFile); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ EVENT_DELIVERY_DELAY; rc = unlink(DummyLink); rc |= remove(DummyFile); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to clean up variation! (errno = %d)\n", errno); } } } /* * TEST : symlink * EXPECTED: DM_EVENT_SYMLINK, DM_RESP_ABORT */ if (DMVAR_EXEC(FILE_SYNC_NAMESP_EVENT_BASE + 8)) { dm_ino_t ino; int fd; /* Variation set up */ eventExpected = DM_EVENT_SYMLINK; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; if ((fd = open(DummyFile, O_RDWR | O_CREAT, DUMMY_FILE_RW_MODE)) != -1) { rc = close(fd); } if (fd == -1 || rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); DMVAR_SKIP(); } else { /* Variation */ eventResponse = DM_RESP_ABORT; EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "symlink(%s, %s)\n", DummyFile, DummyLink); rc = symlink(DummyFile, DummyLink); DMLOG_PRINT(DMLVL_DEBUG, "symlink(%s, %s) returned %d\n", DummyFile, DummyLink, rc); if ((varStatus = DMVAR_CHKFAILEXP(-1, rc, ABORT_ERRNO, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Parent handle NOT root! (%lld vs %d)\n", ino, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_LINK) != 0) { DMLOG_PRINT(DMLVL_ERR, "Symlink entry name NOT correct! (%s vs %s)\n", name1, DUMMY_LINK); varStatus = DMSTAT_FAIL; } else if (strcmp(name2, DummyFile) != 0) { DMLOG_PRINT(DMLVL_ERR, "Symlink contents NOT correct! (%s vs %s)\n", name2, DummyFile); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; rc = remove(DummyFile); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to clean up variation! (errno = %d)\n", errno); } } } /* * TEST : link * EXPECTED: DM_EVENT_LINK, DM_RESP_CONTINUE */ if (DMVAR_EXEC(FILE_SYNC_NAMESP_EVENT_BASE + 9)) { dm_ino_t ino1, ino2, ino3; void *hanp; size_t hlen; int fd; /* Variation set up */ eventExpected = DM_EVENT_LINK; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; if ((fd = open(DummyFile, O_RDWR | O_CREAT, DUMMY_FILE_RW_MODE)) == -1) { /* No clean up */ } else if ((rc = dm_fd_to_handle(fd, &hanp, &hlen)) == -1) { close(fd); } if (fd == -1 || rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); DMVAR_SKIP(); } else { /* Variation */ EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "link(%s, %s)\n", DummyFile, DummyLink); rc = link(DummyFile, DummyLink); DMLOG_PRINT(DMLVL_DEBUG, "link(%s, %s) returned %d\n", DummyFile, DummyLink, rc); if ((varStatus = DMVAR_CHKPASSEXP(0, rc, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino1); rc |= dm_handle_to_ino(hanp2, hlen2, &ino2); rc |= dm_handle_to_ino(hanp, hlen, &ino3); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino1 != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Parent handle NOT root! (%lld vs %d)\n", ino1, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (ino2 != ino3) { DMLOG_PRINT(DMLVL_ERR, "Source link handle NOT correct! (%lld vs %lld)\n", ino2, ino3); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_LINK) != 0) { DMLOG_PRINT(DMLVL_ERR, "Target entry name NOT correct! (%s vs %s)\n", name1, DUMMY_LINK); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ EVENT_DELIVERY_DELAY; rc = close(fd); rc |= remove(DummyFile); rc |= remove(DummyLink); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to clean up variation! (errno = %d)\n", errno); } dm_handle_free(hanp, hlen); } } /* * TEST : link * EXPECTED: DM_EVENT_LINK, DM_RESP_ABORT */ if (DMVAR_EXEC(FILE_SYNC_NAMESP_EVENT_BASE + 10)) { dm_ino_t ino1, ino2, ino3; void *hanp; size_t hlen; int fd; /* Variation set up */ eventExpected = DM_EVENT_LINK; eventReceived = DM_EVENT_INVALID; eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; if ((fd = open(DummyFile, O_RDWR | O_CREAT, DUMMY_FILE_RW_MODE)) == -1) { /* No clean up */ } else if ((rc = dm_fd_to_handle(fd, &hanp, &hlen)) == -1) { close(fd); } if (fd == -1 || rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to set up variation! (errno = %d)\n", errno); DMVAR_SKIP(); } else { /* Variation */ eventResponse = DM_RESP_ABORT; EVENT_DELIVERY_DELAY; DMLOG_PRINT(DMLVL_DEBUG, "link(%s, %s)\n", DummyFile, DummyLink); rc = link(DummyFile, DummyLink); DMLOG_PRINT(DMLVL_DEBUG, "link(%s, %s) returned %d\n", DummyFile, DummyLink, rc); if ((varStatus = DMVAR_CHKFAILEXP(-1, rc, ABORT_ERRNO, eventExpected, eventReceived)) == DMSTAT_PASS) { rc = dm_handle_to_ino(hanp1, hlen1, &ino1); rc |= dm_handle_to_ino(hanp2, hlen2, &ino2); rc |= dm_handle_to_ino(hanp, hlen, &ino3); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "Unable to obtain inode!\n"); varStatus = DMSTAT_FAIL; } else if (ino1 != ROOT_INODE) { DMLOG_PRINT(DMLVL_ERR, "Parent handle NOT root! (%lld vs %d)\n", ino1, ROOT_INODE); varStatus = DMSTAT_FAIL; } else if (ino2 != ino3) { DMLOG_PRINT(DMLVL_ERR, "Source link handle NOT correct! (%lld vs %lld)\n", ino2, ino3); varStatus = DMSTAT_FAIL; } else if (strcmp(name1, DUMMY_LINK) != 0) { DMLOG_PRINT(DMLVL_ERR, "Target entry name NOT correct! (%s vs %s)\n", name1, DUMMY_LINK); varStatus = DMSTAT_FAIL; } } DMVAR_END(varStatus); /* Variation clean up */ eventResponse = DM_RESP_CONTINUE; EVENT_DELIVERY_DELAY; rc = close(fd); rc |= remove(DummyFile); if (rc == -1) { DMLOG_PRINT(DMLVL_DEBUG, "Unable to clean up variation! (errno = %d)\n", errno); } dm_handle_free(hanp, hlen); } } rc = umount(mountPt); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "umount failed! (rc = %d, errno = %d)\n", rc, errno); } pthread_join(tid, NULL); rc = dm_destroy_session(sid); if (rc == -1) { DMLOG_PRINT(DMLVL_ERR, "dm_destroy_session failed! (rc = %d, errno = %d)\n", rc, errno); } DMLOG_STOP(); tst_exit(); }
int main( int argc, char **argv) { char *pathname; char *name; void *hanp1, *hanp2, *hanp3, *fshanp1, *fshanp2, *fshanp3; size_t hlen1, hlen2, hlen3, fshlen1, fshlen2, fshlen3; u_int hash1, hash2, hash3, fshash1, fshash2, fshash3; dm_fsid_t fsid; dm_ino_t ino; dm_igen_t igen; char buffer[100]; char buffer1[100]; char fsbuffer1[100]; char buffer2[100]; char fsbuffer2[100]; char buffer3[100]; char fsbuffer3[100]; int fd; if (Progname = strrchr(argv[0], '/')) { Progname++; } else { Progname = argv[0]; } if (argc != 2) { fprintf(stderr, "usage: %s path\n", argv[0]); exit(1); } pathname = argv[1]; (void)dm_init_service(&name); if (dm_path_to_handle(pathname, &hanp1, &hlen1) != 0) { fprintf(stderr, "dm_path_to_handle failed, %s\n", strerror(errno)); exit(1); } hash1 = dm_handle_hash(hanp1, hlen1); hantoa(hanp1, hlen1, buffer1); fprintf(stdout, " han1: hash %u value %s (dm_path_to_handle)\n", hash1, buffer1); if (dm_handle_is_valid(hanp1, hlen1) == DM_FALSE) { fprintf(stderr, "ERROR: han1 is not valid\n"); } if (dm_path_to_fshandle(pathname, &fshanp1, &fshlen1) != 0) { fprintf(stderr, "dm_path_to_fshandle failed, %s\n", strerror(errno)); exit(1); } fshash1 = dm_handle_hash(fshanp1, fshlen1); hantoa(fshanp1, fshlen1, fsbuffer1); fprintf(stdout, "fshan1: hash %u value %s (dm_path_to_fshandle\n", fshash1, fsbuffer1); if (dm_handle_is_valid(fshanp1, fshlen1) == DM_FALSE) { fprintf(stderr, "ERROR: fshan1 is not valid\n"); } if ((fd = open(pathname, O_RDONLY)) < 0) { fprintf(stderr, "open of %s failed, %s\n", pathname, strerror(errno)); exit(1); } if (dm_fd_to_handle(fd, &hanp2, &hlen2) != 0) { fprintf(stderr, "dm_fd_to_handle failed, %s\n", strerror(errno)); exit(1); } (void)close(fd); hash2 = dm_handle_hash(hanp2, hlen2); hantoa(hanp2, hlen2, buffer2); fprintf(stdout, " han2: hash %u value %s (dm_fd_to_handle)\n", hash2, buffer2); if (dm_handle_is_valid(hanp2, hlen2) == DM_FALSE) { fprintf(stderr, "ERROR: han2 is not valid\n"); } if (dm_handle_to_fshandle(hanp2, hlen2, &fshanp2, &fshlen2) != 0) { fprintf(stderr, "dm_handle_to_fshandle failed, %s\n", strerror(errno)); exit(1); } fshash2 = dm_handle_hash(fshanp2, fshlen2); hantoa(fshanp2, fshlen2, fsbuffer2); fprintf(stdout, "fshan2: hash %u value %s (dm_handle_to_fshandle)\n", fshash2, fsbuffer2); if (dm_handle_is_valid(fshanp2, fshlen2) == DM_FALSE) { fprintf(stderr, "ERROR: fshan2 is not valid\n"); } if (dm_handle_cmp(hanp1, hlen1, hanp2, hlen2)) { fprintf(stderr, "ERROR: han1 and han2 differ in dm_handle_cmp\n"); } if (strcmp(buffer1, buffer2)) { fprintf(stderr, "ERROR: han1 and han2 differ in strcmp\n"); } if (hash1 != hash2) { fprintf(stderr, "ERROR: hash1 and hash2 differ\n"); } if (dm_handle_cmp(fshanp1, fshlen1, fshanp2, fshlen2)) { fprintf(stderr, "ERROR: fshan1 and fshan2 differ in dm_handle_cmp\n"); } if (strcmp(fsbuffer1, fsbuffer2)) { fprintf(stderr, "ERROR: fshan1 and fshan2 differ in strcmp\n"); } if (fshash1 != fshash2) { fprintf(stderr, "ERROR: fshash1 and fshash2 differ\n"); } /* Break the handle into its component parts and display them. Use hantoa() instead of printing the parts directly because some are 32 bits on Veritas and 64 bits on SGI. */ if (dm_handle_to_fsid(hanp1, hlen1, &fsid) != 0) { fprintf(stderr, "dm_handle_to_fsid failed, %s\n", strerror(errno)); exit(1); } hantoa(&fsid, sizeof(fsid), buffer); fprintf(stdout, "fsid %s (dm_handle_to_fsid)\n", buffer); if (dm_handle_to_ino(hanp1, hlen1, &ino) != 0) { fprintf(stderr, "dm_handle_to_ino failed, %s\n", strerror(errno)); exit(1); } hantoa(&ino, sizeof(ino), buffer); fprintf(stdout, "ino %s (dm_handle_to_ino)\n", buffer); if (dm_handle_to_igen(hanp1, hlen1, &igen) != 0) { fprintf(stderr, "dm_handle_to_igen failed, %s\n", strerror(errno)); exit(1); } hantoa(&igen, sizeof(igen), buffer); fprintf(stdout, "igen %s (dm_handle_to_igen)\n", buffer); /* Now use the parts to remake the handle and verify we get the same answer. */ if (dm_make_handle(&fsid, &ino, &igen, &hanp3, &hlen3) != 0) { fprintf(stderr, "dm_make_handle failed, %s\n", strerror(errno)); exit(1); } hash3 = dm_handle_hash(hanp3, hlen3); hantoa(hanp3, hlen3, buffer3); fprintf(stdout, " han3: hash %u value %s (dm_make_handle)\n", hash3, buffer3); if (dm_handle_is_valid(hanp3, hlen3) == DM_FALSE) { fprintf(stderr, "ERROR: han3 is not valid\n"); } if (dm_handle_cmp(hanp1, hlen1, hanp3, hlen3)) { fprintf(stderr, "ERROR: hanp1 and hanp3 differ in dm_handle_cmp\n"); } if (strcmp(buffer1, buffer3)) { fprintf(stderr, "ERROR: hanp1 and hanp3 differ in strcmp\n"); } if (hash1 != hash3) { fprintf(stderr, "ERROR: hash1 and hash3 differ\n"); } if (dm_make_fshandle(&fsid, &fshanp3, &fshlen3) != 0) { fprintf(stderr, "dm_make_fshandle failed, %s\n", strerror(errno)); exit(1); } fshash3 = dm_handle_hash(fshanp3, fshlen3); hantoa(fshanp3, fshlen3, fsbuffer3); fprintf(stdout, "fshan3: hash %u value %s (dm_make_fshandle)\n", fshash3, fsbuffer3); if (dm_handle_is_valid(fshanp3, fshlen3) == DM_FALSE) { fprintf(stderr, "ERROR: fshan3 is not valid\n"); } if (dm_handle_cmp(fshanp1, fshlen1, fshanp3, fshlen3)) { fprintf(stderr, "ERROR: fshan1 and fshan3 differ in dm_handle_cmp\n"); } if (strcmp(fsbuffer1, fsbuffer3)) { fprintf(stderr, "ERROR: fshan1 and fshan3 differ in strcmp\n"); } if (fshash1 != fshash3) { fprintf(stderr, "ERROR: fshash1 and fshash3 differ\n"); } dm_handle_free(hanp1, hlen1); dm_handle_free(hanp2, hlen2); dm_handle_free(hanp3, hlen3); dm_handle_free(fshanp1, fshlen1); dm_handle_free(fshanp2, fshlen2); dm_handle_free(fshanp3, fshlen3); exit(0); }
int main( int argc, char **argv) { dm_sessid_t sid, oldsid, targetsid, *newsidp, *sidbufp; dm_token_t token, *tokenp, *rtokenp, *tokenbufp; dm_attrname_t *attrnamep; dm_off_t off, *offp, *roffp; dm_extent_t *extentp; dm_inherit_t *inheritbufp; dm_stat_t *statp; dm_size_t len, *dmrlenp, *retvalp; dm_attrloc_t *locp; dm_eventset_t *eventsetp; dm_config_t flagname; dm_region_t *regbufp; dm_response_t response; dm_right_t right, *rightp; dm_igen_t igen, *igenp; dm_msgtype_t msgtype; dm_fileattr_t *attrp; dm_boolean_t enable, *exactflagp; dm_timestruct_t *delay; mode_t mode; size_t hlen, dirhlen, hlen1, hlen2, targhlen, *fshlenp, *hlenp; size_t msglen, buflen, *rlenp; u_int nelem, mask, maxmsgs, uflags, *nelemp, maxevent; void *hanp, *dirhanp, *hanp1, *hanp2, *targhanp; void *msgdatap, *bufp, **hanpp, *respbufp, **fshanpp; dm_fsid_t fsid, *fsidp; dm_ino_t ino, *inop; char *cname, *sessinfop, *path, *pathbufp, **versionstrpp; int flags, fd, setdtime, reterror; u_int urc; int rc; dm_ssize_t ssrc; /* Definitions per the prototypes in dmport.h, in the same order. */ rc = dm_clear_inherit(sid, hanp, hlen, token, attrnamep); rc = dm_create_by_handle(sid, dirhanp, dirhlen, token, hanp, hlen, cname); rc = dm_create_session(oldsid, sessinfop, newsidp); rc = dm_create_userevent(sid, msglen, msgdatap, tokenp); rc = dm_destroy_session(sid); rc = dm_downgrade_right(sid, hanp, hlen, token); rc = dm_fd_to_handle(fd, hanpp, hlenp); rc = dm_find_eventmsg(sid, token, buflen, bufp, rlenp); rc = dm_get_allocinfo(sid, hanp, hlen, token, offp, nelem, extentp, nelemp); rc = dm_get_bulkall(sid, hanp, hlen, token, mask, attrnamep, locp, buflen, bufp, rlenp); rc = dm_get_bulkattr(sid, hanp, hlen, token, mask, locp, buflen, bufp, rlenp); rc = dm_get_config(hanp, hlen, flagname, retvalp); rc = dm_get_config_events(hanp, hlen, nelem, eventsetp, nelemp); rc = dm_get_dirattrs(sid, hanp, hlen, token, mask, locp, buflen, bufp, rlenp); rc = dm_get_dmattr(sid, hanp, hlen, token, attrnamep, buflen, bufp, rlenp); rc = dm_get_eventlist(sid, hanp, hlen, token, nelem, eventsetp, nelemp); rc = dm_get_events(sid, maxmsgs, flags, buflen, bufp, rlenp); rc = dm_get_fileattr(sid, hanp, hlen, token, mask, statp); rc = dm_get_mountinfo(sid, hanp, hlen, token, buflen, bufp, rlenp); rc = dm_get_region(sid, hanp, hlen, token, nelem, regbufp, nelemp); rc = dm_getall_disp(sid, buflen, bufp, rlenp); rc = dm_getall_dmattr(sid, hanp, hlen, token, buflen, bufp, rlenp); rc = dm_getall_inherit(sid, hanp, hlen, token, nelem, inheritbufp, nelemp); rc = dm_getall_sessions(nelem, sidbufp, nelemp); rc = dm_getall_tokens(sid, nelem, tokenbufp, nelemp); rc = dm_handle_cmp(hanp1, hlen1, hanp2, hlen2); dm_handle_free(hanp, hlen); urc = dm_handle_hash(hanp, hlen); rc = dm_handle_is_valid(hanp, hlen); rc = dm_handle_to_fshandle(hanp, hlen, fshanpp, fshlenp); rc = dm_handle_to_fsid(hanp, hlen, fsidp); rc = dm_handle_to_igen(hanp, hlen, igenp); rc = dm_handle_to_ino(hanp, hlen, inop); rc = dm_handle_to_path(dirhanp, dirhlen, targhanp, targhlen, buflen, pathbufp, rlenp); rc = dm_init_attrloc(sid, hanp, hlen, token, locp); rc = dm_init_service(versionstrpp); rc = dm_make_handle(&fsid, &ino, &igen, hanpp, hlenp); rc = dm_make_fshandle(&fsid, hanpp, hlenp); rc = dm_mkdir_by_handle(sid, dirhanp, dirhlen, token, hanp, hlen, cname); rc = dm_move_event(sid, token, targetsid, rtokenp); rc = dm_obj_ref_hold(sid, token, hanp, hlen); rc = dm_obj_ref_query(sid, token, hanp, hlen); rc = dm_obj_ref_rele(sid, token, hanp, hlen); rc = dm_path_to_fshandle(path, hanpp, hlenp); rc = dm_path_to_handle(path, hanpp, hlenp); rc = dm_pending(sid, token, delay); rc = dm_probe_hole(sid, hanp, hlen, token, off, len, roffp, dmrlenp); rc = dm_punch_hole(sid, hanp, hlen, token, off, len); rc = dm_query_right(sid, hanp, hlen, token, rightp); rc = dm_query_session(sid, buflen, bufp, rlenp); ssrc = dm_read_invis(sid, hanp, hlen, token, off, len, bufp); rc = dm_release_right(sid, hanp, hlen, token); rc = dm_remove_dmattr(sid, hanp, hlen, token, setdtime, attrnamep); rc = dm_request_right(sid, hanp, hlen, token, uflags, right); rc = dm_respond_event(sid, token, response, reterror, buflen, respbufp); rc = dm_send_msg(sid, msgtype, buflen, bufp); rc = dm_set_disp(sid, hanp, hlen, token, eventsetp, maxevent); rc = dm_set_dmattr(sid, hanp, hlen, token, attrnamep, setdtime, buflen, bufp); rc = dm_set_eventlist(sid, hanp, hlen, token, eventsetp, maxevent); rc = dm_set_fileattr(sid, hanp, hlen, token, mask, attrp); rc = dm_set_inherit(sid, hanp, hlen, token, attrnamep, mode); rc = dm_set_region(sid, hanp, hlen, token, nelem, regbufp, exactflagp); rc = dm_set_return_on_destroy(sid, hanp, hlen, token, attrnamep, enable); rc = dm_symlink_by_handle(sid, dirhanp, dirhlen, token, hanp, hlen, cname, path); rc = dm_sync_by_handle(sid, hanp, hlen, token); rc = dm_upgrade_right(sid, hanp, hlen, token); ssrc = dm_write_invis(sid, hanp, hlen, flags, token, off, len, bufp); exit(0); }
// for a child and manage the supplied event void spawn_child(dm_token_t token, void *hanp, size_t hlen, char *action) { pid_t mypid; pid_t pid; char sidbuf[32]; char tokenbufh[32]; char tokenbufl[32]; dm_attrname_t attrname; dm_attrlist_t bufp[1024]; size_t rlenp; dm_stat_t statp; FILE* mnttab; struct mntent *ent; struct statfs sbuf; dm_ino_t inop; char s[512]; char hname[512]; char *yamssRecallPath="/system/YAMSS_DMRECALL"; char *yamssDMAPIPath="/system/YAMSS_DMERROR"; int fd; int i; int ret; unsigned char c; char extobj[1024]; char inode[32]; time_t rectime, now; struct stat filebuf; // fork a new child pid = fork(); if (pid == 0) { // fork succeeded, we are in the child now mypid=getpid(); // block signals block_signals(mypid); sprintf(sidbuf, "%llx", sid); sprintf(tokenbufh, "%llx", token.high); sprintf(tokenbufl, "%llx", token.low); if (Verbose) { fprintf(stderr, "%d: New child spawn with action=%s, sidbuf=%s, tokenbufh=%s, tokenbufl=%s\n", mypid, action, sidbuf, tokenbufh, tokenbufl); } // green light to mount requests if(!strcmp(action,"MOUNT")) { if (dm_respond_event(sid, token, DM_RESP_CONTINUE, 0, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); exit(1); } if(Verbose) fprintf(stderr,"%d: MOUNT request served\n", mypid); exit(0); } // give error message to write and truncate events // i.e. we don't allow modifications of files on tape if(strcmp(action,"READ")) { // tell client that writing is not permitted if (dm_respond_event(sid, token, DM_RESP_ABORT, EPERM, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); exit(1); } if(Verbose) fprintf(stderr,"%d: %s event rejected with EPERM\n", mypid, action); exit(0); } // get file inode number ret = dm_handle_to_ino(hanp, hlen, &inop); if(ret==-1) { fprintf(stderr,"%d: dm_handle_to_ino: failed, %s\n", mypid, strerror(errno)); // if filesystem is not mounted don't reply with error // it might be a normal mmshutdown and event will be taken over if(!filesystem_is_mounted()) exit(1); if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); } exit(1); } // get dmapi extended attribute with tsm external object id memset((void *)&attrname.an_chars[0], 0, DM_ATTR_NAME_SIZE); memcpy((void *)&attrname.an_chars[0], "IBMObj", 6); ret = dm_get_dmattr(sid, hanp, hlen, DM_NO_TOKEN, &attrname, sizeof(bufp), bufp, &rlenp); if(ret==-1&&errno!=ENOENT) { fprintf(stderr,"%d: dm_get_dmattr: failed, %s\n", mypid, strerror(errno)); // if filesystem is not mounted don't reply with error // it might be a normal mmshutdown and event will be taken over if(!filesystem_is_mounted()) exit(1); if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); } exit(1); } else if(ret==-1) { // get file attributes structure ret=dm_get_fileattr(sid,hanp,hlen,DM_NO_TOKEN,DM_AT_STAT,&statp); if(ret==-1) { fprintf(stderr,"%d: dm_get_fileattr: failed, %s\n", mypid, strerror(errno)); // if filesystem is not mounted don't reply with error // it might be a normal mmshutdown and event will be taken over if(!filesystem_is_mounted()) exit(1); if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); } exit(1); } // IBMObj is not there, double-check if number of blocks on disk is OK if(statp.dt_blocks>=(statp.dt_size/statp.dt_blksize)) { // File has been recalled if (dm_respond_event(sid, token, DM_RESP_CONTINUE, 0, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); // if filesystem is not mounted don't reply with error // it might be a normal mmshutdown and event will be taken over if(!filesystem_is_mounted()) exit(1); if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); } exit(1); } printf("%d: %s event for inode %llu on mount point %s served correctly (file was found to be already on disk)\n", mypid, action, inop, fsname); exit(0); } } // get file attributes structure ret=dm_get_fileattr(sid,hanp,hlen,DM_NO_TOKEN,DM_AT_STAT,&statp); if(ret==-1) { fprintf(stderr,"%d: dm_get_fileattr: failed, %s\n", mypid, strerror(errno)); // if filesystem is not mounted don't reply with error // it might be a normal mmshutdown and event will be taken over if(!filesystem_is_mounted()) exit(1); if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); } exit(1); } // determine mount point for the requested file mnttab = fopen("/etc/mtab", "r"); ent=getmntent(mnttab); while(ent) { if(!statfs(ent->mnt_dir, &sbuf)) { if(statp.dt_dev==*(int*)&sbuf.f_fsid) { break; } } ent = getmntent(mnttab); } fclose(mnttab); if(!ent) { fprintf(stderr,"%d: cannot determine mountpoint\n", mypid); // if filesystem is not mounted don't reply with error // it might be a normal mmshutdown and event will be taken over if(!filesystem_is_mounted()) exit(1); if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); } exit(1); } printf("%d: serving %s event for file on mount point %s with inode number %llu and external object id ", mypid, action, ent->mnt_dir, inop); for(i=0;i<EXTOBJID_LEN;i++) { c=((unsigned char*)bufp)[i]; sprintf(extobj+i*2,"%02X",c); } *(extobj+i*2)=0; printf("%s\n",extobj); // get host name if(gethostname(hname,512)) { // this should never happen... but don't need to fail fprintf(stderr,"%d: cannot get hostname. Setting to dummy\n", mypid); sprintf(hname,"dummy"); } // generate temporary file with unique name containing the external object id of the file to be recalled sprintf(s,"%s%s/%s.%d.XXXXXXXX",ent->mnt_dir,yamssRecallPath,hname,mypid); if((fd=mkstemp(s))<0) { fprintf(stderr,"%d: cannot generate temporary file %s\n",mypid, s); // if filesystem is not mounted don't reply with error // it might be a normal mmshutdown and event will be taken over if(!filesystem_is_mounted()) exit(1); if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); } exit(1); } // write external object id, mount point and inode number into temporary file sprintf(inode,"%llu",inop); if(write(fd,extobj,strlen(extobj))<0 || write(fd," ",1)<0 || write(fd,ent->mnt_dir,strlen(ent->mnt_dir))<0 || write(fd," ",1)<0 || write(fd,inode,strlen(inode))<0 || write(fd,"\n",1)<0) { fprintf(stderr,"%d: cannot write into temporary file %s, %d/%s\n",mypid, s,errno,strerror(errno)); close(fd); if(unlink(s)<0) { fprintf(stderr,"%d: cannot unlink temporary file %s, %d/%s\n",mypid, s, errno,strerror(errno)); } // if filesystem is not mounted don't reply with error // it might be a normal mmshutdown and event will be taken over if(!filesystem_is_mounted()) exit(1); if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); } exit(1); } close(fd); // save start time rectime=time(NULL); // Poll until file is on disk while(1) { // get file attributes structure ret=dm_get_fileattr(sid,hanp,hlen,DM_NO_TOKEN,DM_AT_STAT,&statp); if(ret==-1) { fprintf(stderr,"%d: dm_get_fileattr: failed, %s\n", mypid, strerror(errno)); // if filesystem is not mounted don't reply with error // it might be a normal mmshutdown and event will be taken over if(!filesystem_is_mounted()) exit(1); if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); } exit(1); } if(Verbose&&statp.dt_blocks!=0) { fprintf(stderr,"%d: recalling inode %s dt_blocks %llu dt_size %lld dt_blksize %u\n", mypid, inode, statp.dt_blocks, statp.dt_size, statp.dt_blksize); } // check if IBMObj is there memset((void *)&attrname.an_chars[0], 0, DM_ATTR_NAME_SIZE); memcpy((void *)&attrname.an_chars[0], "IBMObj", 6); ret = dm_get_dmattr(sid, hanp, hlen, DM_NO_TOKEN, &attrname, sizeof(bufp), bufp, &rlenp); if(ret==-1&&errno!=ENOENT) { // if filesystem is not mounted don't reply with error // it might be a normal mmshutdown and event will be taken over if(!filesystem_is_mounted()) exit(1); fprintf(stderr,"%d: dm_get_dmattr: failed, %s\n", mypid, strerror(errno)); if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); } exit(1); } else if(ret==-1) { if(Verbose) { fprintf(stderr,"%d: IBMObj has been removed for inode %s\n", mypid, inode); } } // check if number of blocks on disk is OK and if IBMObj has been removed if(statp.dt_blocks>=(statp.dt_size/statp.dt_blksize)&&ret==-1&&errno==ENOENT) { // File has been recalled if (dm_respond_event(sid, token, DM_RESP_CONTINUE, 0, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); // if filesystem is not mounted don't reply with error // it might be a normal mmshutdown and event will be taken over if(!filesystem_is_mounted()) exit(1); if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); } exit(1); } printf("%d: %s event for inode %llu on mount point %s served correctly\n", mypid, action, inop, ent->mnt_dir); exit(0); } sleep(RECALL_CHECK_SLEEP_TIME); // check if an error flag file has been raised sprintf(s,"%s%s/%s",ent->mnt_dir,yamssDMAPIPath,inode); if(!stat(s, &filebuf) && filebuf.st_ctime>rectime) { fprintf(stderr,"%d: error flag found - cannot recall inode %s on disk\n", mypid, inode); // respond EIO in this case to differentiate with EBUSY generic errors if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); } exit(1); } // check if recall timeout expired now=time(NULL); if((now-rectime)>RECALL_TIMEOUT) { fprintf(stderr,"%d: timed out - cannot recall inode %s on disk after %d seconds\n", mypid, inode, RECALL_TIMEOUT); if (dm_respond_event(sid, token, DM_RESP_ABORT, ETIMEDOUT, 0, NULL)) { fprintf(stderr, "%d: dm_respond_event failed, %d/%s\n", mypid, errno, strerror(errno)); } exit(1); } } } // fork failed if (pid < 0) { fprintf(stderr,"Can't fork child\n"); if (dm_respond_event(sid, token, DM_RESP_ABORT, EBUSY, 0, NULL)) { fprintf(stderr, "dm_respond_event failed, %d/%s\n", errno, strerror(errno)); } return; } // only the father can reach here, increase child counter child_proc_count++; return; }