Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
61 changes: 60 additions & 1 deletion src/libltfs/ltfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,46 @@ bool ltfs_is_interrupted(void)
return interrupted;
}

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

void ltfs_sigcont_set(bool sig_val)
{
caught_sigcont = sig_val;
}

bool ltfs_caught_sigcont(void)
{
return caught_sigcont;
}

int ltfs_extra_signal_handlers(void)
{
ltfs_sighandler_t ret;
ret = signal(SIGCONT, _ltfs_sigcont);
if (ret == SIG_ERR) {
return -LTFS_SIG_HANDLER_ERR;
}

return 0;
}

int ltfs_unset_extra_signal_handler(void)
{
ltfs_sighandler_t rc;
int ret = 0;

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

return ret;
}

/**
* This function can be used to enable libltfs signal handler
* to kill ltfs, mkltfs, ltfsck cleanly
Expand Down Expand Up @@ -2383,12 +2423,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 +2546,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_get_position_from_drive(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
4 changes: 4 additions & 0 deletions src/libltfs/ltfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -592,8 +592,12 @@ 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);
void ltfs_sigcont_set(bool sig_val);
int ltfs_set_signal_handlers(void);
int ltfs_unset_signal_handlers(void);
int ltfs_extra_signal_handlers(void);
int ltfs_unset_extra_signal_handler(void);
int ltfs_finish();

/* Public wrappers for tape_* functions */
Expand Down
25 changes: 24 additions & 1 deletion src/libltfs/tape.c
Original file line number Diff line number Diff line change
Expand Up @@ -1105,7 +1105,7 @@ int tape_get_position(struct device_data *dev, struct tc_position *pos)
/**
* Get current tape position by querying the device.
*/
int tape_update_position(struct device_data *dev, struct tc_position *pos)
int tape_get_position_from_drive(struct device_data *dev, struct tc_position *pos)
{
int ret;

Expand Down 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_current_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,26 @@ ssize_t tape_write(struct device_data *dev, const char *buf, size_t count, bool
count = -LTFS_LESS_SPACE;
}

if (ltfs_caught_sigcont()) {
ret_for_current_position = tape_get_position_from_drive(dev, &current_position);
if (ret_for_current_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;
}

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;
}
}
Comment on lines +1260 to +1261

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's needed to put the "caught_sigcont" value as false before leaving the if() to avoid this check again if it's not necessary

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@amissael95 Could you confirm this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! Done in new commit


// Unset flag to avoid checking it again if it is not needed
ltfs_sigcont_set(false);


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
2 changes: 1 addition & 1 deletion src/libltfs/tape.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ int tape_force_read_only(struct device_data *dev);

int tape_rewind(struct device_data *dev);
int tape_get_position(struct device_data *dev, struct tc_position *pos);
int tape_update_position(struct device_data *dev, struct tc_position *pos);
int tape_get_position_from_drive(struct device_data *dev, struct tc_position *pos);

int tape_seek(struct device_data *dev, struct tc_position *pos);
int tape_seek_eod(struct device_data *dev, tape_partition_t partition);
Expand Down
4 changes: 4 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1241,10 +1241,14 @@ int single_drive_main(struct fuse_args *args, struct ltfs_fuse_data *priv)
ltfsmsg(LTFS_INFO, 14111I);
ltfsmsg(LTFS_INFO, 14112I);
ltfsmsg(LTFS_INFO, 14113I);
/* Set handlers for signals that need to be caught while fuse main is running*/
ltfs_extra_signal_handlers();
ret = fuse_main(args->argc, args->argv, &ltfs_ops, priv);
if (ret != 0) {
ltfsmsg(LTFS_WARN, 14123W, ret);
}
/* Unset extra handlers once fuse main exits */
ltfs_unset_extra_signal_handler();

/* Setup signal handler again to terminate cleanly */
ret = ltfs_set_signal_handlers();
Expand Down
Loading