Skip to content

Conversation

@lukashino
Copy link
Contributor

Follow-up of #13850

Link to ticket: https://redmine.openinfosecfoundation.org/issues/7830

Describe changes:
v2:

  • Hyperscan cache files are now hashed using SHA256 and stored in the hex of a full length (256 bits -> 64 characters)
  • Sensor name is now part of the cache file names, individual instances can now be distinguished with the sensor name
  • The time parsing C function was replaced with a Rust crate
  • In HS: Prune stale cache files from disk v1.1 #13850, Jason asked about the immediate pruning - that is possible, just set the max age to (e.g. 2) seconds.
  • In HS: Prune stale cache files from disk v1.1 #13850, Jason pointed out a synchronization problem of multiple instances sharing one cache folder, e.g., over NFS. This is not addressed here and is currently easily solved by, e.g., sensor name or per-instance folder.

v1:

  • time parsing function from config,
  • "touch" files to signal actively used files,
  • pruning function to remove the HS MPM cache files older than the age specified in the config.

The logic to determine a stale file is currently based on the modification timestamp in the file systems. The accessed time stamp was not used as it may be switched off. Alternatively, we could use a local DB/notekeeping file of the last used files/caches but this approach seemed simpler.

I can also add GitHub CI tests, I thought of some scenarios.

Decision required:

Multiple instances, 1 cache folder

In #13850 we ran into a potential problem, where when multiple instances share one cache folder, one might be just creating the HS cache and the other instance will attempt to load it. Or we might have multiple writers to one file.

This can be easily mitigated by either specifying unique sensor names or not sharing the same folder with each instance. These mitigations, however, miss out on the use case where 1 folder shared by many instances can save the load time because other instances hit the precompiled cache files. The question here is whether we want to allow it.

I looked at solving this, and we can draw inspiration from one of the package managers.
Jason then also suggested the use of the flock() system call, which is also promising, but we need to ensure there is 100% compatibility across operating systems and file systems. It is not supported by Windows, but Windows has an alternative way of doing this.

My current idea was to (when the cached file is not present):

  • attempt to create the .lock file, on failure, give up and compile in SW; on success start compiling the database
  • deserialize the compiled database to file
  • when finished, rename the file to real file, remove the .lock file

Perhaps the - meaning random - file should also have its lock file in the very unlikely case when multiple instances come up with the same name

If we want to proceed with this deployment scenario, we need a ticket.

Lukas Sismis and others added 9 commits October 30, 2025 13:18
To have a system-level overview of when was the last time the file was
used, update the file modification timestamp to to the current time.

This is needed to remove stale cache files of the system.

Access time is not used as it may be, on the system level, disabled.

Ticket: 7830
Hyperscan MPM can cache the compiled contexts to files.
This however grows as rulesets change and leads to bloating
the system. This addition prunes the stale cache files based
on their modified file timestamp.

Ticket: 7830
@lukashino lukashino requested review from a team, jasonish and victorjulien as code owners October 30, 2025 18:40
base64 = "~0.22.1"
bendy = { version = "~0.3.3", default-features = false }
asn1-rs = { version = "~0.6.2" }
parse_duration = "~2.1.1"
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is maintained anymore. Look at humantime instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yup, would need to be replaced.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't know but cargo audit told me so :D
Thanks for the suggestion

@victorjulien victorjulien added the decision-required Waiting on deliberation from the team label Oct 30, 2025
@codecov
Copy link

codecov bot commented Oct 30, 2025

Codecov Report

❌ Patch coverage is 51.06383% with 92 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.14%. Comparing base (56c8db6) to head (6d010bd).
⚠️ Report is 41 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #14212      +/-   ##
==========================================
- Coverage   84.17%   84.14%   -0.03%     
==========================================
  Files        1013     1013              
  Lines      262316   262494     +178     
==========================================
+ Hits       220800   220877      +77     
- Misses      41516    41617     +101     
Flag Coverage Δ
fuzzcorpus 63.33% <1.81%> (-0.03%) ⬇️
livemode 18.72% <1.81%> (-0.02%) ⬇️
pcap 44.57% <1.81%> (-0.02%) ⬇️
suricata-verify 64.84% <1.81%> (-0.04%) ⬇️
unittests 59.18% <51.06%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment on lines -46 to +52
filename, sizeof(filename), "%020" PRIu64 "%s", hs_db_hash, hash_file_path_suffix);
if (r != (uint64_t)(20 + strlen(hash_file_path_suffix)))
filename, sizeof(filename), "%s_%s%s", sensor_name, hs_db_hash, hash_file_path_suffix);
if (r != (uint64_t)(strlen(sensor_name) + 1 + strlen(hs_db_hash) +
strlen(hash_file_path_suffix)))
Copy link
Member

Choose a reason for hiding this comment

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

What happens if my sensor name is "foo/bar"? Or "../../../../../etc/"? :) I don't think we have any restrictions on the sensor-name, but if using in a path we probably need to. One option is to create a hash from the name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, that would need to be addressed. I could take the sensor name as one of the things I hash with SHA256 so we wouldn't even need to extend the naming scheme (to <sensor_name>__v1.hs)

@suricata-qa
Copy link

Information: QA ran without warnings.

Pipeline = 28174

@lukashino
Copy link
Contributor Author

Decision made:
Keep it simple and make a note in the docs that different instances should have their own folders to not risk simultaneous read and/or writes

Sensor name won't be part of the cache file name.

@lukashino lukashino removed the decision-required Waiting on deliberation from the team label Nov 3, 2025
@lukashino
Copy link
Contributor Author

new in #14270

@lukashino lukashino closed this Nov 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants