Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions messages/libltfs/root.txt
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,8 @@ v
17290I:string { "Partitioning the medium with the destructive method." }
17291I:string { "Unpartitioning the medium with the destructive method." }
17292I:string { "Current position is (%llu, %llu), Error position is (%llu, %llu)." }
17293I:string { "Position mismatch. Cached tape position = %llu. Current tape position = %llu." }
17294I:string { "Continue signal (%d) received" }

// For Debug 19999I:string { "%s %s %d." }

Expand Down
46 changes: 45 additions & 1 deletion src/libltfs/ltfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,18 @@ bool ltfs_is_interrupted(void)
return interrupted;
}

bool caught_sigcont = false;
void _ltfs_sigcont(int signal)
{
ltfsmsg(LTFS_INFO, 17294I, signal);
caught_sigcont = true;
}

bool ltfs_caught_sigcont(void)
{
return caught_sigcont;
}

/**
* This function can be used to enable libltfs signal handler
* to kill ltfs, mkltfs, ltfsck cleanly
Expand Down Expand Up @@ -249,6 +261,15 @@ int ltfs_set_signal_handlers(void)
return -LTFS_SIG_HANDLER_ERR;
}

ret = signal(SIGCONT, _ltfs_sigcont);
if (ret == SIG_ERR) {
signal(SIGINT, SIG_DFL);
signal(SIGHUP, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
return -LTFS_SIG_HANDLER_ERR;
}

return 0;
}
#endif
Expand Down Expand Up @@ -283,6 +304,10 @@ int ltfs_unset_signal_handlers(void)
if (rc == SIG_ERR)
ret = -LTFS_SIG_HANDLER_ERR;

rc = signal(SIGCONT, SIG_DFL);
if (rc == SIG_ERR)
ret = -LTFS_SIG_HANDLER_ERR;

return ret;
}
#endif
Expand Down Expand Up @@ -2383,12 +2408,13 @@ int ltfs_write_index(char partition, char *reason, struct ltfs_volume *vol)
struct tape_offset old_selfptr, old_backptr;
struct ltfs_timespec modtime_old = { .tv_sec = 0, .tv_nsec = 0 };
bool generation_inc = false;
struct tc_position physical_selfptr;
struct tc_position physical_selfptr, current_position;
char *cache_path_save = NULL;
bool write_perm = (strcmp(reason, SYNC_WRITE_PERM) == 0);
bool update_vollock = false;
int volstat = -1, new_volstat = 0;
char *bc_print = NULL;
unsigned long long diff;

CHECK_ARG_NULL(vol, -LTFS_NULL_ARG);

Expand Down Expand Up @@ -2505,6 +2531,24 @@ int ltfs_write_index(char partition, char *reason, struct ltfs_volume *vol)
vol->index->backptr = old_backptr;
goto out_write_perm;
}

/* Get the tape position from the tape drive by using the SCSI command READPOS*/
ret = tape_update_position(vol->device, &current_position);
if (ret < 0) {
/* Return error since the current tape position was unable to be determined, so there could be an undetected position mismatch */
ltfsmsg(LTFS_ERR, 11081E, ret);
return -1;
}

/* Prior to writing the index, compare the current location of the head position to the head location
that is kept in the cache of ltfs (physical_selfptr). If they are different return error (-1) */
diff = ((unsigned long long)physical_selfptr.block - (unsigned long long)current_position.block);
if (diff) {
/* Position mismatch, diff not equal zero */
ltfsmsg(LTFS_INFO, 17293I, (unsigned long long)physical_selfptr.block, (unsigned long long)current_position.block);
return -1;
}

old_selfptr = vol->index->selfptr;
vol->index->selfptr.partition = partition;
vol->index->selfptr.partition = vol->label->part_num2id[physical_selfptr.partition];
Expand Down
1 change: 1 addition & 0 deletions src/libltfs/ltfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ int ltfs_fs_init(void);
void ltfs_set_log_level(int log_level);
void ltfs_set_syslog_level(int syslog_level);
bool ltfs_is_interrupted(void);
bool ltfs_caught_sigcont(void);
int ltfs_set_signal_handlers(void);
int ltfs_unset_signal_handlers(void);
int ltfs_finish();
Expand Down
21 changes: 21 additions & 0 deletions src/libltfs/tape.c
Original file line number Diff line number Diff line change
Expand Up @@ -1187,6 +1187,9 @@ int tape_spacefm(struct device_data *dev, int count)
ssize_t tape_write(struct device_data *dev, const char *buf, size_t count, bool ignore_less, bool ignore_nospc)
{
ssize_t ret;
struct tc_position current_position;
int ret_for_update_position = 0;
unsigned long long diff = 0;

CHECK_ARG_NULL(dev, -LTFS_NULL_ARG);
CHECK_ARG_NULL(buf, -LTFS_NULL_ARG);
Expand Down Expand Up @@ -1241,6 +1244,24 @@ ssize_t tape_write(struct device_data *dev, const char *buf, size_t count, bool
count = -LTFS_LESS_SPACE;
}

if (ltfs_caught_sigcont()) {
ltfsmsg(LTFS_DEBUG, 16503D, "ltfs_caught_sigcont", "tape_write");
ret_for_update_position = tape_update_position(dev, &current_position);
if (ret_for_update_position) {
/* Return error since the current tape position was unable to be determined, so there could be an undetected position mismatch */
ltfsmsg(LTFS_ERR, 11081E, ret);
return -LTFS_WRITE_ERROR;
}

ltfsmsg(LTFS_INFO, 11334I, "compare offset in tape_write", (unsigned long long)dev->position.block, (unsigned long long)current_position.block);
diff = ((unsigned long long)dev->position.block - (unsigned long long)current_position.block);
if (diff) {
/* Position mismatch, diff not equal zero */
ltfsmsg(LTFS_INFO, 17293I, (unsigned long long)dev->position.block, (unsigned long long)current_position.block);
return -LTFS_WRITE_ERROR;
}
}

ltfs_mutex_lock(&dev->append_pos_mutex);
dev->append_pos[dev->position.partition] = dev->position.block;
ltfs_mutex_unlock(&dev->append_pos_mutex);
Expand Down
Loading