int closeOutFile(void) { if (!ofdIsOpen) return 0; USD_CLOSE(ofd); ofdIsOpen = 0; /* Decrement the number of volumes to restore */ nrestore--; return 0; }
int openOutFile(struct volumeHeader *headerPtr) { afs_int32 len; int ch; int rc; int oflag; int skip, first; afs_hyper_t size; /* If we were asked to skip this volume, then skip it */ if (nskip) { nskip--; return 0; } /* Skip if we are not to restore any */ if (!nrestore) return 0; /* Get the volume name and strip off the BK or RO extension */ if (outfile) { strcpy(filename, outfile); } else { strcpy(filename, headerPtr->volumeName); len = strlen(filename); if ((len > 7) && (strcmp(".backup", filename + len - 7) == 0)) { filename[len - 7] = 0; } else if ((len > 9) && (strcmp(".readonly", filename + len - 9) == 0)) { filename[len - 9] = 0; } } if (ask) { first = 1; skip = 0; printf("Press return to retreive volume %s (%u) to file %s; " "s" " to skip\n", headerPtr->volumeName, headerPtr->volumeID, filename); do { ch = getchar(); if ((first == 1) && (ch == 's')) skip = 1; if ((first == 1) && (ch == 'q')) exit(0); first = 0; } while (ch != '\n'); if (skip) { printf("Will not restore volume %s\n", headerPtr->volumeName); return 0; } } else { printf("Retrieve volume %s (%u) to file %s\n", headerPtr->volumeName, headerPtr->volumeID, filename); } /* Should I append the date onto the end of the name? */ /* Open the file to write to */ if (headerPtr->contd == TC_VOLCONTD) { /* Continuation of dump */ oflag = USD_OPEN_RDWR; } else { /* An all new dump */ oflag = USD_OPEN_RDWR | USD_OPEN_CREATE; } rc = usd_Open(filename, oflag, 0664, &ofd); if (rc != 0) { fprintf(stderr, "Unable to open file %s. Skipping. Code = %d\n", filename, rc); nrestore--; return 0; } if (headerPtr->contd != TC_VOLCONTD) { hzero(size); rc = USD_IOCTL(ofd, USD_IOCTL_SETSIZE, &size); if (rc != 0) { fprintf(stderr, "Unable to open file %s. Skipping. Code = %d\n", filename, rc); USD_CLOSE(ofd); nrestore--; return 0; } } ofdIsOpen = 1; return 0; }
static int ForkClose(usd_handle_t fd) { return (USD_CLOSE(fd)); }
static int ForkClose(usd_handle_t fd) { int rc; /* return code from system calls */ int i; /* loop index */ int pid; /* process ID of child process */ int status; /* exit status of child process */ int close_rc, parent_close_rc; /* return codes from close */ int pipefd[2]; /* pipe for child return status */ int ctlpipe[2]; /* pipe for message to child */ int forkflag; /* flag set when ready to fork */ int unixfd; #ifdef AFS_PTHREAD_ENV forkflag = 0; /* No need to fork if using pthreads */ #else forkflag = 1; #endif /* create pipe for getting return code from child */ if (forkflag) { rc = pipe(pipefd); if (rc < 0) { printf("butm: Cannot create pipe for CLOSE process. Error %d\n", errno); forkflag = 0; } } /* create pipe for notifying child when to close */ if (forkflag) { rc = pipe(ctlpipe); if (rc < 0) { close(pipefd[0]); close(pipefd[1]); printf("butm: Cannot create pipe for CLOSE process. Error %d\n", errno); forkflag = 0; } } if (forkflag) { pid = fork(); if (pid < 0) { close(pipefd[0]); close(pipefd[1]); close(ctlpipe[0]); close(ctlpipe[1]); printf("butm: Cannot create CLOSE child process. Error %d\n", errno); forkflag = 0; } } if (!forkflag) { /* problem starting child process */ close_rc = USD_CLOSE(fd); parent_close_rc = close_rc; } else if (pid == 0) { /* child process */ /* close all unneccessary file descriptors */ /* note: as painful as it is, we have to reach under the covers of * the usd package to implement this functionality. */ unixfd = (intptr_t)(fd->handle); for (i = 3; i < _POSIX_OPEN_MAX; i++) { if (i != unixfd && i != ctlpipe[0] && i != pipefd[1]) { close(i); } } /* * The parent writes the control pipe after it closes the device. * We don't actually care about the read; we're just using it to * block until the parent is ready. But we must do something * with the result, to avoid complier warnings on some platforms. */ if (read(ctlpipe[0], &close_rc, sizeof(int)) < 0) ; /* don't care */ close(ctlpipe[0]); /* do the close */ close_rc = USD_CLOSE(fd); /* * Send the return code back to the parent. * If this fails, there's nothing we can do, but we must test * it in order to avoid complier warnings on some platforms. */ if (write(pipefd[1], &close_rc, sizeof(int)) < 0) ; /* don't care */ exit(0); } else { /* parent process */ close(pipefd[1]); close(ctlpipe[0]); POLL(); /* * close the device, this should have no effect as long as the * child has not closed */ parent_close_rc = USD_CLOSE(fd); /* notify the child to do its close */ rc = write(ctlpipe[1], &close_rc, sizeof(int)); /* just send garbage */ if (rc != sizeof(int)) { printf("butm: Error communicating with CLOSE process. Error %d\n", errno); } close(ctlpipe[1]); /* read the result from the child process */ rc = read(pipefd[0], &close_rc, sizeof(int)); if (rc != sizeof(int)) { /* logging is enough, since we wrote a file mark the */ /* return code from the close doesn't really matter */ printf("butm: No response from CLOSE process. Error %d\n", errno); close_rc = 0; } close(pipefd[0]); /* get the completion status from the child process */ rc = waitpid(pid, &status, 0); while (rc < 0 && errno == EINTR) { rc = waitpid(pid, &status, 0); } if (rc < 0) { printf("butm: Cannot get status of CLOSE process. Error %d\n", errno); } else if (status != 0) { printf ("butm: Unexpected exit status 0x%04x from CLOSE process. Error %d\n", status, errno); } /* if either process received an error, then return an error */ if (parent_close_rc < 0) { close_rc = parent_close_rc; } SLEEP(1); } return (close_rc); }
static int ForkOpen(char *device) { int rc; /* return code from system calls */ int i; /* loop index */ int pid; /* process ID of child process */ int status; /* exit status of child process */ int open_rc; /* return code from open */ int pipefd[2]; /* pipe for child return status */ int forkflag; /* flag set when ready to fork */ usd_handle_t fd; /* handle returned from open */ #ifdef AFS_PTHREAD_ENV forkflag = 0; /* No need to fork if using pthreads */ #else forkflag = 1; #endif /* create pipe for getting return code from child */ if (forkflag) { rc = pipe(pipefd); if (rc < 0) { printf("butm: Cannot create pipe for OPEN process. Error %d\n", errno); forkflag = 0; } } if (forkflag) { pid = fork(); if (pid < 0) { close(pipefd[0]); close(pipefd[1]); printf("butm: Cannot create child process for OPEN. Error %d\n", errno); forkflag = 0; } } if (!forkflag) { /* problem starting child process */ /* *return success, the caller will discover any problems * when it opens the device. */ open_rc = 0; } else if (pid == 0) { /* child process */ /* close all unneccessary file descriptors */ for (i = 3; i < _POSIX_OPEN_MAX; i++) { if (i != pipefd[1]) { close(i); } } /* try the open */ open_rc = usd_Open(device, USD_OPEN_RDONLY, 0, &fd); if (open_rc == 0) { USD_CLOSE(fd); } /* * Send the return code back to the parent. * If this fails, there's nothing we can do, but we must test * it in order to avoid complier warnings on some platforms. */ if (write(pipefd[1], &open_rc, sizeof(open_rc)) < 0) ; /* don't care */ exit(0); } else { /* parent process */ close(pipefd[1]); POLL(); /* read the result from the child process */ rc = read(pipefd[0], &open_rc, sizeof(open_rc)); if (rc != sizeof(open_rc)) { /* this is not a problem since we will reopen the device anyway */ printf("butm: No response from OPEN process. Error %d\n", errno); open_rc = 0; } close(pipefd[0]); /* get the completion status from the child process */ rc = waitpid(pid, &status, 0); while (rc < 0 && errno == EINTR) { rc = waitpid(pid, &status, 0); } if (rc < 0) { printf("butm: Cannot get status of OPEN process. Error %d\n", errno); } else if (status != 0) { printf ("butm: Unexpected OPEN process exit status 0x%04x. Error %d \n", status, errno); } SLEEP(1); } return (open_rc); }
int fileMarkSize(char *tapeDevice) { afs_uint32 nFileMarks, nBlocks, nbfTape; double tpSize, fmSize; afs_uint32 bufferSize = 16384; usd_handle_t hTape; FILE *logFile; int count = 0; afs_uint32 countr; afs_int32 code = 0; code = usd_Open(tapeDevice, (USD_OPEN_RDWR | USD_OPEN_WLOCK), 0777, &hTape); if (code) { printf("Can't open tape device %s\n", tapeDevice); fflush(stdout); exit(1); } logFile = fopen("fms.log", "w+"); if (logFile == NULL) { printf("Can't open log file\n"); fflush(stdout); exit(1); } fprintf(logFile, "fms test started\n"); fflush(logFile); code = rewindTape(hTape); if (code) { fprintf(logFile, "Can't rewind tape\n"); fflush(logFile); ERROR(code); } /* measure capacity of tape */ nbfTape = 0; countr = 0; while (1) { code = dataBlock(hTape, bufferSize); nbfTape++; count++; countr++; if (code) break; if (count >= 5) { count = 0; printf("\rwrote block: %d", nbfTape); } } fprintf(logFile, "wrote %d blocks\n", nbfTape); fflush(logFile); printf("\rwrote %d blocks\n", nbfTape); printf("Finished data capacity test - rewinding\n"); /* reset the tape device */ code = USD_CLOSE(hTape); if (code) { fprintf(logFile, "Can't close tape device at end of pass 1\n"); fflush(logFile); printf("Can't close tape device %s\n", tapeDevice); goto error_exit; } code = usd_Open(tapeDevice, (USD_OPEN_RDWR | USD_OPEN_WLOCK), 0777, &hTape); if (code) { fprintf(logFile, "Can't open tape device for pass 2\n"); fflush(logFile); printf("Can't open tape device %s\n", tapeDevice); goto error_exit; } code = rewindTape(hTape); if (code) { fprintf(logFile, "Can't rewind tape\n"); fflush(logFile); ERROR(code); } /* now measure file mark size */ nFileMarks = 0; nBlocks = 0; count = 0; countr = 0; while (1) { code = dataBlock(hTape, bufferSize); nBlocks++; if (code) break; code = fileMark(hTape); nFileMarks++; if (code) break; count++; countr++; if (count >= 2) { count = 0; printf("\rwrote %d blocks, %d filemarks", nBlocks, nFileMarks); } } printf("\nFinished filemark test\n"); tpSize = (double)nbfTape *(double)bufferSize; fmSize = (((double)nbfTape - (double)nBlocks) * (double)bufferSize) / (double)nFileMarks; printf("Tape capacity is %.0f bytes\n", tpSize); printf("File marks are %.0f bytes\n", fmSize); fprintf(logFile, "Tape capacity is %.0f bytes\n", tpSize); fprintf(logFile, "File marks are %.0f bytes\n", fmSize); fflush(logFile); fclose(logFile); error_exit: USD_CLOSE(hTape); return (code); }