obsproject / obs-studio

OBS Studio - Free and open source software for live streaming and screen recording
https://obsproject.com
GNU General Public License v2.0
60.22k stars 7.97k forks source link

v4l2loopback module not found #3845

Closed gregoa closed 3 years ago

gregoa commented 3 years ago

Platform

Operating system and version: Debian unstable OBS Studio version: 26.1.0-rc2

Current Behavior

"warning: v4l2loopback not installed, virtual camera disabled"

Additional information

The message is from plugins/linux-v4l2/linux-v4l2.c which tries system("modinfo v4l2loopback &>/dev/null"). This fails on e.g. Debian, as modinfo is in /sbin which is not in $PATH by default for a non-root user. (So this probably affects half of the Linux world.)

(As a side note, &> is a bashism; >/dev/null 2>&1 would be the portable variant. - And I just see that this is already covered in #3826)

After changing the code to

--- a/plugins/linux-v4l2/linux-v4l2.c
+++ b/plugins/linux-v4l2/linux-v4l2.c
@@ -31,7 +31,7 @@
 {
    bool loaded = false;

-   int ret = system("modinfo v4l2loopback &>/dev/null");
+   int ret = system("/sbin/modinfo v4l2loopback >/dev/null 2>&1");

    if (ret == 0)
        loaded = true;

the virual camera works. Probably this is just a hack and not portable to non Debianoid systems …

(It just takes the "wrong" of my v4l2loopback devices, i.e. the first one (plugins/linux-v4l2/v4l2-output.c), but that's a different story and I believe already covered in a different issue.).

WizardCM commented 3 years ago

The bashism you mentioned has a PR open already here: https://github.com/obsproject/obs-studio/pull/3826/files

gregoa commented 3 years ago

On Mon, 07 Dec 2020 16:49:06 -0800, Matt Gajownik wrote:

The bashism you mentioned has a PR open already here: https://github.com/obsproject/obs-studio/pull/3826/files

Right, sorry for finding this only after pressing "submit". But that's a side issue anyway.

derrod commented 3 years ago

Is modinfo not in your $PATH?

gregoa commented 3 years ago

Correct, that's what I already wrote in my inital message :)

modinfo is /sbin/modinfo and /sbin is not in $PATH for ordinary users.

gregoa commented 3 years ago

/ The question of making the used device configurable was e.g. mentioned in https://github.com/obsproject/obs-studio/pull/3182#issuecomment-697103614 /

kkartaltepe commented 3 years ago

This is not the correct solution because modinfo is not in /sbin/ on all distributions either. You can extend the path before calling OBS for the time being.

kkartaltepe commented 3 years ago

We can extend path in the system call to include /sbin which should work for debian users.

RytoEX commented 3 years ago

This appears to be a duplicate of #3788 which was closed. The issue of whether to use a full absolute path or rely on $PATH was discussed in the original PR for Linux virtual camera output in this comment thread.

See also: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=918754

We can extend path in the system call to include /sbin which should work for debian users.

@kkartaltepe Does that mean you have an idea of how to resolve this within OBS?

derrod commented 3 years ago

Is there really no better way to do this in the first place than to call system() at all?

kkartaltepe commented 3 years ago

PATH=$PATH:/sbin modinfo works in bash in sh mode, i don't have dash to immediately test in Debian, but i presume it should work.

You can review the source for modinfo, while its not entirely complex its more than I wanted to insist we re-implement in our platform layer.

gregoa commented 3 years ago

Right, this issue affects more than just modinfo (I just didn't hit pkexec (which I don't even have installed) or modprobe, because I have v4l2loopback installed and loaded).

gregoa commented 3 years ago

PATH=$PATH:/sbin modinfo works in dash as well.

kkartaltepe commented 3 years ago

installing pkexec is the responsibility of your packager.

gregoa commented 3 years ago

I can confirm that this patch (again, only targetting the modinfo part, but that's relevant for me) works:

--- a/plugins/linux-v4l2/linux-v4l2.c
+++ b/plugins/linux-v4l2/linux-v4l2.c
@@ -31,7 +31,7 @@
 {
    bool loaded = false;

-   int ret = system("modinfo v4l2loopback &>/dev/null");
+   int ret = system("PATH=$PATH:/sbin modinfo v4l2loopback >/dev/null 2>&1");

    if (ret == 0)
        loaded = true;
gregoa commented 3 years ago

On Mon, 07 Dec 2020 17:31:35 -0800, Kurt Kartaltepe wrote:

installing pkexec is the responsibility of your packager.

Correct. And if they make it a hard dependency I will maintain my own package, because

fzwoch commented 3 years ago

Alternatively, how about a check for the existence of /sys/module/v4l2loopback?

$ stat /sys/module/v4l2loopback/
  File: /sys/module/v4l2loopback/
  Size: 0           Blocks: 0          IO Block: 4096   directory
Device: 14h/20d Inode: 37547       Links: 6
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-12-09 09:26:39.124580674 +0100
Modify: 2020-12-09 08:47:37.525079367 +0100
Change: 2020-12-09 08:47:37.525079367 +0100
 Birth: -

Or go even further

$ cat /sys/module/v4l2loopback/initstate 
live

My proposal

diff --git a/plugins/linux-v4l2/linux-v4l2.c b/plugins/linux-v4l2/linux-v4l2.c
index 0df54450..429c1c26 100644
--- a/plugins/linux-v4l2/linux-v4l2.c
+++ b/plugins/linux-v4l2/linux-v4l2.c
@@ -16,6 +16,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include <obs-module.h>
 #include <util/platform.h>
+#include <sys/stat.h>

 OBS_DECLARE_MODULE()
 OBS_MODULE_USE_DEFAULT_LOCALE("linux-v4l2", "en-US")
@@ -29,11 +30,12 @@ extern struct obs_output_info virtualcam_info;

 static bool v4l2loopback_installed()
 {
+       struct stat buffer;
        bool loaded = false;

-       int ret = system("modinfo v4l2loopback >/dev/null 2>&1");
+       int ret = stat("/sys/module/v4l2loopback", &buffer);

-       if (ret == 0)
+       if (ret == 0 && S_ISDIR(buffer.st_mode))
                loaded = true;

        return loaded;
gregoa commented 3 years ago

On Wed, 09 Dec 2020 00:33:40 -0800, Florian Zwoch wrote:

Alternatively, how about a check for the existence of /sys/module/v4l2loopback?

I think that does something different: while modinfo checks if the module exists (whether loaded or not), /sys/module/v4l2loopback only exists when the module is actually loaded.

fzwoch commented 3 years ago

Yeah, I see..

phedders commented 3 years ago

On Wed, 09 Dec 2020 00:33:40 -0800, Florian Zwoch wrote: Alternatively, how about a check for the existence of /sys/module/v4l2loopback? I think that does something different: while modinfo checks if the module exists (whether loaded or not), /sys/module/v4l2loopback only exists when the module is actually loaded.

But isn't that exactly what we want? To know if it is loaded?

gregoa commented 3 years ago

On Thu, 10 Dec 2020 06:26:45 -0800, phedders wrote:

I think that does something different: while modinfo checks if the module exists (whether loaded or not), /sys/module/v4l2loopback only exists when the module is actually loaded. But isn't that exactly what we want? To know if it is loaded?

In my understanding, there are two checks:

What I stumbled across was the first check.

gbschenkel commented 3 years ago

Hi, I am a Slackware user, and maintainer of few packages. As in Slackware, modprobe resides in /sbin, and normal user don't have it on path. Besides modinfo can be run using fullpath, modprobe is command supposed to be used by root and services, like the other binaries from /sbin.

Saying that, I think the owner of the computer need load the v4l2loopback kernel module when the computer boots, and not when running OBS Studio, else in some distro, the people will start using OBS with sudo just to load this module.

What you can do is a script to been add to systemd or init.d to load the module on boot. And maybe, this instructions was to be learned from l4d2loopback development team, not here.

For conclude my point of view, I moslty agree with @gregoa, I think we can check if the module is loaded, verifying /sys/module/v4l2loopback as been described, and use modinfo to see if the module is installed(PATH=/sbin:/usr/sbin/:/usr/local/sbin modinfo v4l2loopback) BUT I think is not responsability of OBS Studio to load it.

I think you can let the virtualcam option allowed in Tools, and if the module is not loaded or presented, show up a message inside of it with instructions to allow it, maybe a url to a wiki in this github repo.

As for me, I will apply a patch on my build script to run /sbin/modinfo until a definitive decision been made, and I have already added it on my /etc/rc.d/rc.modules.local/ to load the module on boot.

#!/bin/sh

# /etc/rc.d/rc.modules.local

# The Linux kernel source is the best place to look for documentation
# for the many available kernel modules.  This can be found under
# /usr/src/linux-$VERSION/Documentation/.

# Almost all necessary modules are automatically loaded when needed,
# but there are a few exceptions.  Here's a (not all-inclusive) list,
# so uncomment any of the below entries or add others as needed:
# Note that you could also create/edit rc.modules-$version if you
# only wanted specific modules loaded for particular kernels.

#/sbin/modprobe tun            # Universal TUN/TAP device driver
#/sbin/modprobe sg             # Generic SCSI support for SATA DVD-RW

# Enable DKMS module rebuilding
if [ -x /usr/lib/dkms/dkms_autoinstaller ]; then
  echo "Running DKMS autoinstaller"
  /usr/lib/dkms/dkms_autoinstaller start
fi

# Load v4l2loopback (Virtual Camera)
/sbin/modprobe v4l2loopback
bnordgren commented 3 years ago

The flatpak package for OBS does not have the modinfo command, but can examine the /sys and /proc filesystems of the running kernel as a user. I would encourage adoption of the latter strategy.

I don't know whether one can load a kernel module from within the sandboxed environment or not. Allowing such an action would seem to indicate a pretty weak and leaky sandbox....

kkartaltepe commented 3 years ago

else in some distro, the people will start using OBS with sudo just to load this module.

Im not sure why you make this assumption. No one runs bash as root, they use sudo. Similarly OBS does not need to be run as root.

The flatpak package for OBS does not have the modinfo command, but can examine the /sys and /proc filesystems of the running kernel as a user. I would encourage adoption of the latter strategy.

Feel free to review modinfo's source code to see why its preferable to a simpler method. Im not sure anyone is particularly keen on maintaining a parallel implementation of modinfo just for OBS's platform layer so its probably easier to package it into your flatpak environment.

phedders commented 3 years ago

On Tue, 2020-12-29 at 12:24 -0800, Kurt Kartaltepe wrote:

else in some distro, the people will start using OBS with sudo just to load this module. Im not sure why you make this assumption. No one runs bash as root, they use sudo. Similarly OBS does not need to be run as root. I think his point was exactly that people might start running obs under sudo so that it could modprobe... which would be daft but might seem to be an obvious "fix" for less experienced users. The flatpak package for OBS does not have the modinfo command, but can examine the /sys and /proc filesystems of the running kernel as a user. I would encourage adoption of the latter strategy. Feel free to review modinfo's source code to see why its preferable to a simpler method. Im not sure anyone is particularly keen on maintaining a parallel implementation of modinfo just for OBS's platform layer so its probably easier to package it into your flatpak environment. I think OBS should not be managing the hardware - that is root/systems job.

kkartaltepe commented 3 years ago

which would be daft but might seem to be an obvious "fix" for less experienced users.

A fix for what exactly? OBS already prompts the user for permissions when its required.

bnordgren commented 3 years ago

Ah. I thought this was just a check for an installed kernel module, not part of a system that would try to load it if it exists. This opens another can of worms because the notion that modinfo has some kind of value beyond just checking to see if it is currently loaded is predicated on the assumption that the kernel module lives in /lib/module/version. A related unexamined assumption is that "if the kernel module is found by modinfo, it must be compiled against the running kernel", as the output of modinfo is not examined. Maybe OK if it was found in /lib/module/version, but really a bad bet otherwise.

In terms of Flatpak combined with an ostree based distro like Fedora Silverblue, /lib/modules is immutable and v4l2loopback is not packaged. The orthodox (and only) means of getting this kernel module in place is to compile it yourself and manually load it from the directory in which you compiled it...because you cannot add the module to the immutable directory in which it would otherwise live. (See https://github.com/coreos/rpm-ostree/issues/1091) Note that this makes the assumption that the kernel module was compiled against the running kernel less of a sure thing. They may package this kernel module someday, but note that ticket was opened in 2017 and tomorrow is 2021.

The following appear to be the options for some kind of path forward:

Really the only thing within my sphere of control is that last one. From the peanut gallery, the most aesthetically pleasing solution would be one which makes the fewest hard-coded assumptions about the system on which OBS is running. (Assumptions such as: modinfo is in the path of the user running OBS; modinfo lives in a particular directory; the kernel module is in /lib/modules, the specified kernel module was compiled against the running kernel, etc.) A zero-assumption approach is just "try using the loopback interface and see if it works." Next up from that would be having a way to specify the correct parameters to test for and start kernel modules, whilst supplying reasonable defaults. Hard-coding these features essentially makes quite a few assumptions, then immediately etches them in stone as a one-size-fits-all solution.

I think the moral of this story is: When one tries to be clever, one should make sure that "being clever" solves more problems than it creates.

However, I'm in the cheap seats and have no say in what the OBS project decides to do, nor how the flatpak packagers decide to package things. My workaround will be the last option presented above...

soulflyman commented 3 years ago

Hi, I'm running obs 26.1 on Kubuntu 20.04 and get the following error when clicking on the "Start Virtual Camera" button:

sh: 1: pkexec: not found

Package v4l2loopback-dkms and v4l2loopback-tools are installed and pkexec is also available on the system.

Is this a related error to this issue or should I open a new one?

nursoda commented 3 years ago

I just installed Arch from scratch After installing the kernel module, obs-studio's integrated virtual camera worked. No issues.

soulflyman commented 3 years ago

Hi, I'm running obs 26.1 on Kubuntu 20.04 and get the following error when clicking on the "Start Virtual Camera" button:

sh: 1: pkexec: not found

Package v4l2loopback-dkms and v4l2loopback-tools are installed and pkexec is also available on the system.

Is this a related error to this issue or should I open a new one?

Okay I found this line in the source code of OBS https://github.com/obsproject/obs-studio/blob/b9a1516254f722fc9367140e28ade7ec8b5539d5/plugins/linux-v4l2/v4l2-output.c#L56

I copied the command pkexec modprobe v4l2loopback exclusive_caps=1 card_label='OBS Virtual Camera' && sleep 0.5 pasted it into my terminal as user and hit enter, then I was asked for my password and after that the command worked without any issues and I have a virtual camera.

But I still don't know why it does not work when OBS tries to run this command.

kkartaltepe commented 3 years ago

4133 resolves the issues mentioned with checks against manually loaded kernel modules in restricted runtimes and the checks and loading on debian machines.

Its my assumption that users with pkexec not found on ubuntu are likely installing snap packaging which doesnt have pkexec. If you find that's not the case please open a separate bug.

TrevCan commented 3 years ago

I am aware this issue is now closed, but I'd like to point out how I solved it in case some one does not know this. First of all, I must mention, I have 3 kernels installed (linux-lts, linux, linux-zen). I installed obs through the regular repos (not AUR) as well as v4l2loopback-dkms. I was also getting the message when starting obs (around the lines of): v4l2loopback device not detected. Virtual Camera not started.

I believe what I did wrong was not have all the kernel headers installed. I was running the linux-zen kernel but did not have the linux-zen-headers installed, maybe that's what didn't detect it? So I installed my correct kernel headers, then cloned the v4l2loopback repo (https://github.com/umlaeute/v4l2loopback/) and ran make as well as # make install, after that, and after a restart (since I had updated my kernel) I was able to run it gracefully. Hope this helps.

RobLoach commented 2 years ago

Confirming what TrevCan ran into, this time on Ubuntu MATE 20.04. The Virtual Camera was not starting, with sh: 1: pkexec: not found errors. Installing v4l2loopback fixed the virtual cam.

git clone https://github.com/umlaeute/v4l2loopback.git
cd v4l2loopback
make
sudo make install
iuliandita commented 10 months ago

I am aware this issue is now closed, but I'd like to point out how I solved it in case some one does not know this. First of all, I must mention, I have 3 kernels installed (linux-lts, linux, linux-zen). I installed obs through the regular repos (not AUR) as well as v4l2loopback-dkms. I was also getting the message when starting obs (around the lines of): v4l2loopback device not detected. Virtual Camera not started.

I believe what I did wrong was not have all the kernel headers installed. I was running the linux-zen kernel but did not have the linux-zen-headers installed, maybe that's what didn't detect it? So I installed my correct kernel headers, then cloned the v4l2loopback repo (https://github.com/umlaeute/v4l2loopback/) and ran make as well as # make install, after that, and after a restart (since I had updated my kernel) I was able to run it gracefully. Hope this helps.

I was in the same situation. Installed the linux-headers and the v4l2loopback-dkms packages, rebooted, but the virtual camera was still not available. Reading your message, I realized I also had to install the linux-zen-headers package, since that's what I use (duh!). I did that, reinstalled the v4l2loopback-dkms package, and the virtual camera showed up, I didn't even have to reboot. Thanks everyone!

MeikelLP commented 2 weeks ago

I sadly still have this issue:

# uname -r
6.1.0-26-amd64

# dpkg --get-selections | egrep "^(v4l|linux-)" | egrep -v "(latency|libc)" | tr -s "\t " " " | cut -d " " -f 1
linux-base
linux-compiler-gcc-12-x86
linux-headers-6.1.0-26-amd64
linux-headers-6.1.0-26-common
linux-headers-amd64
linux-image-6.1.0-25-amd64
linux-image-6.1.0-26-amd64
linux-image-amd64
linux-kbuild-6.1
v4l2loopback-dkms

I have to manually call

pkexec modprobe v4l2loopback exclusive_caps=1 card_label='OBS Virtual Camera' && sleep 0.5

and obs does setup a virtual camera after restarting OBS

What am I doing wrong?