Auto-connect interfaces request for auto-cpufreq

Hello,

I’m the author of auto-cpufreq - Automatic CPU speed & power optimizer for Linux app, for which I made a snap. Hence the reason for this request.

I’ve created and thoroughly tested the snap itself and changes can be found in “snap” branch. After this request is approved and snap published/released I’ll merge these changes with master branch.

It needs a classic confinement because it does system related operations to change CPU speed/turbo/governors/et cetera and in future other power related operations.

Looking forward to your review and any other questions you may have,

Thanks,

Adnan

1 Like

From what I can understand of this snap, it requires read access to various CPU attributes, and write access to the CPU governor. @ahodzic is this correct?

Currently there is no snap interface which provides access to modify the CPU governor - however the existing cpu-control interface does provide read access to most of these attributes - I suggest that we expand the cpu-control interface to provide write access to the governor attributes which should then allow this snap to be strictly confined - @jdstrand does this seem reasonable to you?

@ahodzic We can look at updating the AppArmor profile for cpu-control to allow this access - from what I can glean the following change should allow the cpu specific parts needed by auto-cpufreq:

If you could please review this list and provide any feedback that would be great, then we can look at getting this change merged into snapd so auto-cpufreq can function as a strictly confined snap in the future.

@alexmurray nice, thank you.

I briefly tried to make this a “strictly” confidue snap, but due to inability to read certain values, like the ones you mentioned in cpu-control and temperatures. For which I tried using ic2 but without much success, I simply switched to “classic” which allowed me to have all the functionality I needed.

But if I can fix these on the fly, I would definitely prefer to have “strictly” confined snap instead of “classic”.

Give me some time to add the necessary “interfaces” and I’ll get back to you.

If you need temperature information, hardware-observe should hopefully be sufficient.

Okay, I will give it a try later, currently I have following interfaces:

    plugs:
      - cpu-control
      - system-observe
      - hardware-observe
      - system-files

Since this is my first snap, how do I automatically make connection to these interfaces after snap is installed? As currently, I have to manually run:

snap connect auto-cpufreq:cpu-control
snap connect auto-cpufreq:system-observe
snap connect auto-cpufreq:hardware-observe
snap connect auto-cpufreq:system-files

to proper connections.

It is normal that all of these require manual connection (as per https://snapcraft.io/docs/supported-interfaces none of these are auto-connected by default). However, you can request that an assertion from the snap store be granted which can specify that these are auto-connected for your snap - see Process for aliases, auto-connections and tracks for more information. In this case, you could simply change the title of this existing thread and post a comment asking for auto-connection.

Okay great, in that case after I’m done with everything I’ll request for these interfaces to be “auto-connect” for my snap.

Regarding my snap in strict confinement, I made the necessary changes and this is how my snapcraft.yml looks like now.

I noticed during snap install I’ll get following INFO message:

2020-02-10T18:11:22+01:00 INFO snap "auto-cpufreq" has bad plugs or slots: system-files (cannot add system-files plug: needs valid "read" or "write" attribute)

After that I run:

snap connect auto-cpufreq:cpu-control
snap connect auto-cpufreq:system-observe
snap connect auto-cpufreq:hardware-observe

to make manual interface connections, which as a result look like:

$ snap connections auto-cpufreq
Interface         Plug                           Slot               Notes
cpu-control       auto-cpufreq:cpu-control       :cpu-control       manual
hardware-observe  auto-cpufreq:hardware-observe  :hardware-observe  manual
log-observe       auto-cpufreq:log-observe       :log-observe       manual
process-control   auto-cpufreq:process-control   :process-control   manual
system-observe    auto-cpufreq:system-observe    :system-observe    manual
upower-observe    auto-cpufreq:upower-observe    :upower-observe    -

However, when I run sudo auto-cpufreq --live I’ll get following output:

----------------------------- System information ------------------------------

Linux distro: Ubuntu 19.10 (Eoan Ermine)
Linux kernel: 5.3.0-29-generic
Driver: intel_pstate
Architecture: x86_64
Processor: Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
Cores: 8

------------------------------ Current CPU states ------------------------------

CPU max frequency: 
4600 MHz

CPU frequency for each core:

CPU0: 4257 MHz
CPU1: 4306 MHz
CPU2: 4153 MHz
CPU3: 4123 MHz
CPU4: 4232 MHz
CPU5: 4264 MHz
CPU6: 4204 MHz
CPU7: 4188 MHz

Temperature for each physical core:

CPU0 temp: 83°C
CPU1 temp: 77°C
CPU2 temp: 83°C
CPU3 temp: 71°C

---------------------------- CPU frequency scaling ----------------------------

Battery is: charging
Setting to use "performance" governor
/snap/auto-cpufreq/x1/usr/bin/cpufreqctl: line 142: /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor: Permission denied
/snap/auto-cpufreq/x1/usr/bin/cpufreqctl: line 142: /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor: Permission denied
/snap/auto-cpufreq/x1/usr/bin/cpufreqctl: line 142: /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor: Permission denied
/snap/auto-cpufreq/x1/usr/bin/cpufreqctl: line 142: /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor: Permission denied
/snap/auto-cpufreq/x1/usr/bin/cpufreqctl: line 142: /sys/devices/system/cpu/cpu4/cpufreq/scaling_governor: Permission denied
/snap/auto-cpufreq/x1/usr/bin/cpufreqctl: line 142: /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor: Permission denied
/snap/auto-cpufreq/x1/usr/bin/cpufreqctl: line 142: /sys/devices/system/cpu/cpu6/cpufreq/scaling_governor: Permission denied
/snap/auto-cpufreq/x1/usr/bin/cpufreqctl: line 142: /sys/devices/system/cpu/cpu7/cpufreq/scaling_governor: Permission denied

Total CPU usage: 6.7 %
Total system load: 1.11 

High load, setting turbo boost: on
/bin/sh: 1: cannot create /sys/devices/system/cpu/intel_pstate/no_turbo: Permission denied

-------------------------------------------------------------------------------

			"auto-cpufreq" refresh in: 4

Any idea why I’m getting “permission denied” on /sys/devices/system/cpu/cpu* and /sys/devices/system/cpu/intel_pstate/no_turbo or am I doing something wrong?

I also noticed that when I run: sudo auto-cpufreq --install I get following output:

/snap/auto-cpufreq/x1/lib/python3.6/site-packages/power/linux.py:100: UserWarning: Unable to read properties of /sys/class/power_supply/BAT0: [Errno 13] Permission denied: '/sys/class/power_supply/BAT0/type'
  warnings.warn("Unable to read properties of {path}: {error}".format(path=supply_path, error=str(e)))
/snap/auto-cpufreq/x1/lib/python3.6/site-packages/power/linux.py:100: UserWarning: Unable to read properties of /sys/class/power_supply/AC: [Errno 13] Permission denied: '/sys/class/power_supply/AC/type'
  warnings.warn("Unable to read properties of {path}: {error}".format(path=supply_path, error=str(e)))

----------------- auto-cpufreq daemon installed and running -----------------

To view live log, run:
auto-cpufreq --log

To disable and remove auto-cpufreq daemon, run:
sudo auto-cpufreq --remove

-------------------------------------------------------------------------------

As it seems I also have permission issues with: /sys/class/power_supply/*

Either way, looking forward to any comments that you may have, thanks!

because you try to write to it which is currently not allowed and needs @alexmurray’s PR above to be merged … then you will be able to try it out from the edge channel …

i suggest you comment on the PR above as @alexmurray asked so all the files you need write access to are covered …

… and drop the system-files interface from your snapcraft.yaml, it is useless without exact path specifications (and as you have seen it also causes an error on snap install ...)

because you try to write to it which is currently not allowed and needs @alexmurray’s PR above to be merged … then you will be able to try it out from the edge channel …

i suggest you comment on the PR above as @alexmurray asked so all the files you need write access to are covered …

Thanks for the clarification, as suggested I’ve commented on @alexmurray change.

… and drop the system-files interface from your snapcraft.yaml, it is useless without exact path specifications (and as you have seen it also causes an error on snap install ... )

Reason I have system-files is because I need to write log file to: /var/log/auto-cpufreq.log when service is enabled.

wow, why dont you just use:

apps:
...
    service:
      command: bin/auto-cpufreq --daemon
      daemon: simple
...

and let systemd journald do all the logging (like it is done with most other snaps) … that also allows you to use the snap logs auto-cpufreq command beyond journalctl …

I did it like this because in my original setup, systemd will write to /var/log/auto-cpufreq.log and then I could easily read this file which gives me the cleanest log output, i.e:

----------------------------- System information ------------------------------

Linux distro: Ubuntu 19.10 eoan
Linux kernel: 5.3.0-29-generic
Driver: intel_pstate
Architecture: x86_64
Processor: Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
Cores: 8

------------------------------ Current CPU states ------------------------------

CPU max frequency: 
1800 MHz

CPU frequency for each core:

CPU0: 1800 MHz
CPU1: 1800 MHz
CPU2: 1800 MHz
CPU3: 1800 MHz
CPU4: 1800 MHz
CPU5: 1800 MHz
CPU6: 1800 MHz
CPU7: 1800 MHz

Temperature for each physical core:

CPU0 temp: 51°C
CPU1 temp: 49°C
CPU2 temp: 49°C
CPU3 temp: 49°C

---------------------------- CPU frequency scaling ----------------------------

Battery is: discharging
Setting to use: powersave

Total CPU usage: 2.2 %
Total system load: 1.3 

Load optimal, setting turbo boost: off

-------------------------------------------------------------------------------

			"auto-cpufreq" refresh in: 5

If I could get same output using snap logs auto-cpufreq or journalctl -fu snap.auto-cpufreq.service.service that would be great, but I tried already with unsatisfactory results. Hence why I thought it would be the best to have:

  service:
    command: bin/auto-cpufreq --daemon 2>&1 | tee -a /var/log/auto-cpufreq.log

Which gives me exactly what I want.

i’d then just use:

    command: bin/auto-cpufreq --daemon 2>&1 | tee -a $SNAP_DATA/auto-cpufreq.log

then your log automatically goes to /var/snap/auto-cpufreq/auto-cpufreq.log and you wont need to ask permission from the security team for your snap to take over /var/log through system-files :slight_smile:

I like this idea the most :slight_smile: and have dropped system-files and set:

service:
    command: bin/auto-cpufreq --daemon 2>&1 | tee -a $SNAP_DATA/auto-cpufreq.log

Which I verified writes proper logs to $SNAP_DATA/auto-cpufreq.log in snap env.

However, after I run: auto-cpufreq --log which I set to read (/var/snap/auto-cpufreq/auto-cpufreq.log) I get following output:

/snap/auto-cpufreq/x1/lib/python3.6/site-packages/power/linux.py:100: UserWarning: Unable to read properties of /sys/class/power_supply/BAT0: [Errno 13] Permission denied: '/sys/class/power_supply/BAT0/type'
  warnings.warn("Unable to read properties of {path}: {error}".format(path=supply_path, error=str(e)))
/snap/auto-cpufreq/x1/lib/python3.6/site-packages/power/linux.py:100: UserWarning: Unable to read properties of /sys/class/power_supply/AC: [Errno 13] Permission denied: '/sys/class/power_supply/AC/type'
  warnings.warn("Unable to read properties of {path}: {error}".format(path=supply_path, error=str(e)))
tail: cannot open '$SNAP_DATA/auto-cpufreq.log' for reading: No such file or directory
tail: no files remaining

Problem is that /var/snap/auto-cpufreq/auto-cpufreq.log doesn’t exist on local file system.
But interestingly enough /var/snap/auto-cpufreq/x1/auto-cpufreq.log does, and that’s where my logs are located.

I could set it to read from $SNAP_DATA/auto-cpufreq.log which also doesn’t exists on local file system. But is it wise/update proof if I export $SNAP_DATA to /var/snap/auto-cpufreq/x1? As $SNAP_DATA/auto-cpufreq.log is located in /var/snap/auto-cpufreq/x1/auto-cpufreq.log on local file system?

Whoops !!! sorry, indeed, SNAP_DATA points always to:

/var/snap/<snapname>/<version>/

the snap design gives a guarantee that your data is always copied forward and backward with new revisions or when going back a revision to a former package version so you dont really need to worry about the version in the path …

another probably valuable bit of information is that the symlink /var/snap/<snapname>/current always points to the running version so if you set your auto-cpufreq --log configuration to point to the “/current” dir (or make it use the SNAP_DATA environment variable directly) you should be good …

Perfect, I made all the necessary changes and they work as expected, thank you for your assistance! Much appreciated.

Now all that’s left is to wait for @alexmurray to merge proposed changes in his git commit.

I also hope I can get approval for auto-connect on:

  • cpu-control
  • system-observe
  • hardware-observe

After which I can proceed with publishing of auto-cpufreq snap.

I have adjusted the change since the files listed in the original commit are actually symlinks back to the profile directories and AppArmor will resolve these to their final filenames - this is submitted as https://github.com/snapcore/snapd/pull/8127 - note if this gets merged it should be available in the upcoming snapd 2.44 release.

1 Like

@ahodzic Can you please change the topic of this request to be for auto-connect of the required interfaces since classic confinement will not be needed?

@alexmurray of course, done.

+1 from me for auto-connect of cpu-control system-observe and hardware-observe for auto-cpufreq - can other @reviewers please vote too?