Skip to content
Open
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);

Choose a reason for hiding this comment

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

Why to check the position again just after we already checked the position basically one line above?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The position check of above lines is basically reading the position in ltfs cache, the position read by the "tape_update_position" is the real position drive, that is why we are comparing those two positions in the next lines.

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;
}
}
Comment on lines +1263 to +1264

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


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