Quantcast
Channel: Active questions tagged linux-kernel - Stack Overflow
Viewing all 12211 articles
Browse latest View live

Kernel boots in Emergency mode after adding system calls

$
0
0

I have been given the task of modifying slob.c to use a best-fit algorithm when doing memory allocation. What I'm having trouble with is implementing a syscall that returns the amount of free memory and the amount claimed. When recompiling the kernel after making changes, the kernel boots in emergency mode, and says something along /boot or /root could not be mounted. As it's booting it also prints a printk message I included inside both functions a lot of times.

Kernel info: Linux ubuntu 3.6.6 x86_64

I have followed these: https://medium.com/anubhav-shrimal/adding-a-hello-world-system-call-to-linux-kernel-dad32875872

https://www.kernel.org/doc/html/v4.14/process/adding-syscalls.html

In attempting to implement the syscall to no avail. Essentially I've added the functions to

include/linux/syscalls.h:

asmlinkage long sys_func1(void);
asmlinkage long sys_func2(void);

include/asm-generic/unistd.h:

#define __NR_func1 x+1
__SYSCALL(__NR_func1, sys_func1)
#define __NR_func1 x+2
__SYSCALL(__NR_func1, sys_func2)

where x+1 and x+2 are the next available numbers there and also updated the __NR_syscalls count.

both syscall tables (_64 & _32)

//64
x    common   func1   sys_func1
x+1  common   func2   sys_func2

//32
x   i386   func1   sys_func1
x+1 i386   func2   sys_func2

This was by following the 2nd link from kernel.org. The instructions provided to me don't explain how to add a syscall, but refer me to a document explaining how to make modules, so my next try will be adding it as a module if that's even possible.

The following is the code I have at the end of the slob.c file It uses two global arrays to keep track of free and claimed memory. These are the functions I'm trying to use.

{...}

asmlinkage long sys_get_slob_amt_free(void)
{

    printk(KERN_INFO "Inside slob free\n");
    long sum = 0;
    int i = 0;

    for(i = 0; i < 100; i++)
    {
        sum += memFree[i];

    }


    return (sum / 100);

}

asmlinkage long sys_get_slob_amt_claimed(void)
{

    printk(KERN_INFO "Inside slob claimed\n");
    long sum = 0;
    int i = 0;

    for(i = 0; i < 100; i++)
    {
        sum += memClaimed[i];

    }

    return (sum / 100);
}

On my later attempts (after adding the syscall to what I said above) the printk statements are repeated numerous times upon booting the kernel. On earlier attempts (when I only added the syscall to the syscall_32.tbl) the syscalls would return -1 or garbage values, which leads me to believe that it was calling other functions.


How nl80211 library & cfg80211 work?

$
0
0

I want to learn about how nl80211 and cfg80211 works in detail. Function flow, how nl80211 interact with network tools like wpa_supplicant, iw.

Plz suggest me some useful links or books to refer.

Where are DECLARE_PER_CPU variables stored in kernel

$
0
0

I am trying to understand how current macro retrieves struct task_struct of the process.

I am trying to understand for x86 architecture, and after exploring kernel source, struck at the following code:

#include <linux/compiler.h>
#include <asm/percpu.h>

#ifndef __ASSEMBLY__
struct task_struct;

DECLARE_PER_CPU(struct task_struct *, current_task);

static __always_inline struct task_struct *get_current(void)
{
    return percpu_read_stable(current_task);
}

#define current get_current()

#endif /* __ASSEMBLY__ */

#endif /* _ASM_X86_CURRENT_H */
  1. Where are the variables declared in DECLARE_PER_CPU stored in memory.
  2. Are they at fixed location or in CPU Registers.
  3. I am still unable to get, how this will give the task_struct pointer

Can anyone explain it. Thanks for your time and patience

error: expected declaration specifiers or ‘...’ before ‘off_t' [closed]

$
0
0
void *orig_mmap(void *addr, size_t lenght, int prot, int flags, int fd, off_t offset);

I don't understand the off_t indentifier and it is causing the error I mention above.

Interrupt parameter: device tree configuration?

$
0
0

I am currently writing a device tree node to configure SCISIS752 Dual Channel UART with I2C which is connected to the slave address 0x4d. I am also using a clock of 1.8432MHz. The IRQ pin of SCISIS752 is attached to an IO Expander GPIO which is gpiopin 456 in my case. My dts configuration:

  sc16is752@4d {
    compatible = "nxp,sc16is752";
    reg = <0x4d>; 
    clocks = <&sc16is752_clk>;
    interrupt-parent = <&gpio3>;
    interrupts = <7 2>; 
    gpio-controller;
    #gpio-cells = <2>;

    sc16is752_clk: sc16is752_clk {
        compatible = "fixed-clock";
        #clock-cells = <0>;
        clock-frequency = <1843200>;
    };};

I am confused on setting the values of interrupt-parent and interrupts to make this configuration work.

Aws ec2 patch upgrade for Linux 7 using automation

$
0
0

Hi are u aware like what is best approach to upgrade the kernal patches on AWS ec2 instances using automation tool like terraform, cloud formation or any best practices. Where I can upgrade and roll back via Jenkins or team city jobs ?

Is there a way to switch to another process context from linux kernel module

$
0
0

I try to change the "current" process to another task as the scheduler do it but it's more complicated than I thought. In other words, I'm looking for KeStackAttachProcess linux equivalent.

Flow: ProcessA -> send ioctl to my device driver with some pid -> In my kernel module I find the task by it's pid ->"context switch" to ProcessB -> do my stuff on this process context

Cannot check for null getting error in an if statement

$
0
0

I have a system call for the Linux kernel. When checking for null in an if statement, the process terminates:

unable to handle kernel null pointer reference at [position]

The faulty code below:

struct task_struct *task;
int found = 0;
if ((task = find_task_by_vpid(pid))) // task was found when code ran
{
    found = 1;
}
if (found)
{
    char* nothing = "NULL";
    struct vm_area_struct *vma;
    ...
    vma = task->mm->mmap;
    while (vma != NULL)
    {
    ...
        if (!vma->vm_file->f_path.dentry->d_name.name)
        {
            printk("The file name mapped to this is %s\n", nothing);
        }
        ...
    }
    ...
    return 0;
}

Why does this not work?


How to enable Google Container Optimized OS swap limit support

$
0
0

I'm running Kubernetes/Docker on Google Container Optimized OS on a GCE instance. When I run docker info it says

$ docker info
Containers: 116
 Running: 97
 Paused: 0
 Stopped: 19
Images: 8
Server Version: 1.11.2
Storage Driver: overlay
 Backing Filesystem: extfs
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins: 
 Volume: local
 Network: null host bridge
Kernel Version: 4.4.21+
Operating System: Container-Optimized OS from Google
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 14.67 GiB
Name: REDACTED
ID: REDACTED
Docker Root Dir: /var/lib/docker
Debug mode (client): false
Debug mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support

The last line says that there is no swap limit support. I'm having trouble figuring out how to enable swap limit support. I found instructions for Ubuntu/Debian here.

My problem is that my docker containers get OOMKilled as soon as they reach their memory limit instead of trying swapping. I want the containers to use swap as a buffer instead of dying immediately.

What kernel options is Google's Container Optimized OS built with?

$
0
0

I'm having trouble finding the kernel options that Google's Container Optimized OS is built with. I tried looking at the usual locations like boot/config-* and /proc/config.gz, but didn't find anything. I searched the source code and didn't find anything either, but I'm probably just searching wrong.

The specific option I'm curious about is CONFIG_CFS_BANDWIDTH and whether it is enabled or not. Thanks!

Why doesnt apt-get update work on kali linux?

$
0
0

I am trying to update Kali Linux but the update is not working.

I tried reinstalling the system two times but it doesn't work anyway Here it is what happens

root@kali:~# apt-get update
Reading package lists... Done
root@kali:~#

What is the maximum buffer size that we can pass using nl? If we increase the PAGE_SIZE in kernel will it help to increase the buffer size?

$
0
0

I am working on an application(ARM platform) that uses netlink messages to pass a buffer of size 8k to kernel space driver to fetch some data from the driver. I have allocated the required memory for the nl message using function nlmsg_alloc_size, But When the buffer size exceeds size of 4k, we are not getting data from driver, even though the driver is able to receive the NL command with buffer.

So we checked the kernel source and found that the buffer size is limited to 4096 for ARM in kernel.

So is it possible to send a nl message with more than 4k buffer? If so, please suggest a solution.

Thanks.

Problem In sending signals from my Linux kernel module to user space application

$
0
0

I am using an embedded board with Linux operating system.

This board has a push button and Led.

  • Button file path is : /dev/input/event0 , and has a code 260 .

  • Led file Path is : /sys/class/leds .

I want to control Led, switch on and off, through the button. Besides, I want to use signals to notify about Pushing button event occurring. The signal will be sent to user space when the event is occurred.

For that I developed Linux kernel loadable module and principal user space application.

This is the module :

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/siginfo.h>    //siginfo
#include <linux/rcupdate.h>    //rcu_read_lock
#include <linux/sched/signal.h>    //find_task_by_pid_type
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include<linux/slab.h>
#include <linux/input.h>
#include <linux/device.h>
#include <linux/fs.h> 


#define SIG_TEST 44    // we choose 44 as our signal number (real-time signals are in the range of 33 to 64)
#define BTN_FILE_PATH "/dev/input/event0"


char *str = BTN_FILE_PATH;
int file;

struct file *f;


static ssize_t write_pid(struct file *pfile, const char __user *buffer,
                                size_t length, loff_t *offset)
{
    return 0;
}



static ssize_t read_pid(struct file *pfile, char __user *buffer,
                                size_t length, loff_t *offset)
{


     char mybuf[10];
    enum { MAX_BUF_SIZE = 4096 };
    size_t buf_size = 0;
    char *buf = NULL;
    ssize_t total = 0;
    ssize_t rc = 0;
    struct task_struct *t;
    struct input_event  *ev;
    int yalv;

    int ret;
    struct siginfo info;
    int pid =0; 

    /* Allocate temporary buffer. */
    if (length) {
        buf_size = min_t(size_t, MAX_BUF_SIZE, length);
        ev = kmalloc(buf_size, GFP_KERNEL);
        if (ev == NULL) {
            return -ENOMEM;
        }
    }

    /* read the value from user space */
    if(length > 10)
        return -EINVAL;
    copy_from_user(mybuf, buffer, length);
    sscanf(mybuf, "%d", &pid);
    printk("pid = %d\n", pid);

    rcu_read_lock();
    t = pid_task(find_vpid(pid), PIDTYPE_PID);  //find the task_struct associated with this pid
    if(t == NULL){
        printk("no such pid\n");
        rcu_read_unlock();
        return -ENODEV;
    }
    rcu_read_unlock();

 /* Read file to buffer in chunks. */

        size_t amount = min_t(size_t, length, buf_size);

        rc = kernel_read(f, ev, amount, offset);
        if (rc > 0) {
            /* Have read some data from file. */
            if (copy_to_user(buffer, ev, rc) != 0) {
                /* Bad user memory! */
                rc = -EFAULT;
            } else {
                /* Update totals. */
                total += rc;
                buffer += rc;
                *offset += rc;
                length -= rc;

        for (yalv = 0; yalv < (int) (rc / sizeof(struct input_event)); yalv++) {
            if (ev[yalv].type == EV_KEY) {
                printk("signal was send\n");
                if (ev[yalv].value == 0)
                     ret = send_sig_info(SIG_TEST, &info, t);    //send the signal
                         if (ret < 0) {
                            printk("error sending signal\n");
                        kfree(buf);
                            return ret;
                         }

            }
        }
                if (rc < amount) {
                    /* Didn't read the full amount, so terminate early. */
                    rc = 0;
                }
            }

    } 


    /* Free temporary buffer. */

    kfree(buf);

}


static const struct file_operations my_fops = {
    .owner = THIS_MODULE,
    .write = write_pid,
    .read = read_pid,
};

static int __init signalexample_module_init(void)
{

    /* we need to know the pid of the user space process
      * -> we use debugfs for this. As soon as a pid is written to 
      * this file, a signal is sent to that pid
      */
    /* only root can write to this file (no read) */
    register_chrdev(240, "Simple Char Drv", &my_fops);
    file = debugfs_create_file("signalconfpid", 0200, NULL, NULL, &my_fops);
    f = filp_open(str, 0 , O_RDONLY);

    return 0;
}
static void __exit signalexample_module_exit(void)
{
    unregister_chrdev(240, "Simple Char Drv");
    debugfs_remove(file);

}

This is the principal user-space application :

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>

#include <linux/input.h>

#define BTN_FILE_PATH "/dev/input/event0"
#define LED_PATH "/sys/class/leds"
#define red "red"
#define SIG_TEST 44
#define BUFFER_LENGTH 256

void change_led_state(char *led_path, int led_value)
{
    char    lpath[64];
    FILE    *led_fd;

    strncpy(lpath, led_path, sizeof(lpath) - 1);
    lpath[sizeof(lpath) - 1] = '\0';

    led_fd = fopen(lpath, "w");

    if (led_fd == NULL) {
        fprintf(stderr, "simplekey: unable to access led\n");
        return;
    }

    fprintf(led_fd, "%d\n", led_value);

    fclose(led_fd);
}

void reset_leds(void)
{
    change_led_state(LED_PATH "/" red "/brightness", 0);
}

int configure_leds(void)
{
    FILE    *r_fd;
    char    *none_str = "none";

    /* Configure leds for hand control */
    l_fd = fopen(LED_PATH "/" red "/trigger", "w");

    if ( r_fd == NULL) {
        perror("simplekey: unable to configure led");
        return -EACCES;
    }

    fprintf(r_fd, "%s\n", none_str);

    fclose(r_fd);

    /* Switch off leds */
    reset_leds();

    return 0;
}

void eval_keycode(int code)
{
    static int red_state = 0;

    switch (code) {
    case 260:
        printf("BTN left pressed\n");

        /* figure out red state */
        red_state = red_state ? 0 : 1;

        change_led_state(LED_PATH "/" red "/brightness", red_state);
        break;

    }
}


void receiveData(int n, siginfo_t *info, void *unused) 
{
    printf("received value %i\n", info->si_int);   
}

int main ( int argc, char **argv )
{
    int ret;
    int nc;
    int fd;
    int configfd;
    char buf[10];
    char buffer[BUFFER_LENGTH];
    /* setup the signal handler for SIG_TEST 
      * SA_SIGINFO -> we want the signal handler function with 3 arguments
      */
    struct sigaction sig;
    sig.sa_sigaction = receiveData;
    sig.sa_flags = SA_SIGINFO;
    sigaction(SIG_TEST, &sig, NULL);

    fd = open("/dev/char_device", O_RDONLY);             // Open the device with read access   
    if (fd < 0)
    {
            perror("Failed to open the device...");
            return errno;
    }
     sprintf(buffer, "%i", getpid());   
    nc = read(fd,buffer,strlen(buffer));
    if (nc < 0)
    {
            perror("Failed to read the message from the device.");
            return errno;
    }

    ret = configure_leds();
    if (ret < 0)
    exit(1);

    reset_leds();
    getchar();

    return 0;
}

After inserting the module and running the application, this returns to me only the PID of my user code, but when I push the button, nothing happens. The signal is not send as I guess.

If anyone would help me, I will be grateful. Thank you!

The maximum buffer size that we can pass using netlink and PAGE_SIZE influence on it

$
0
0

I am working on an application (ARM platform) that uses netlink messages to pass a buffer of size 8k to kernel space driver to fetch some data from the driver. I have allocated the required memory for the nl message using function nlmsg_alloc_size(), but when the buffer size exceeds size of 4k, we are not getting data from driver, even though the driver is able to receive the netlink command with buffer.

So we checked the kernel source and found that the buffer size is limited to 4096 for ARM in kernel.

So is it possible to send netlink message with more than 4k buffer? If so, please suggest a solution.

Walking page tables of a process in Linux

$
0
0

i'm trying to navigate the page tables for a process in linux. In a kernel module i realized the following function:

static struct page *walk_page_table(unsigned long addr)
{
    pgd_t *pgd;
    pte_t *ptep, pte;
    pud_t *pud;
    pmd_t *pmd;

    struct page *page = NULL;
    struct mm_struct *mm = current->mm;

    pgd = pgd_offset(mm, addr);
    if (pgd_none(*pgd) || pgd_bad(*pgd))
        goto out;
    printk(KERN_NOTICE "Valid pgd");

    pud = pud_offset(pgd, addr);
    if (pud_none(*pud) || pud_bad(*pud))
        goto out;
    printk(KERN_NOTICE "Valid pud");

    pmd = pmd_offset(pud, addr);
    if (pmd_none(*pmd) || pmd_bad(*pmd))
        goto out;
    printk(KERN_NOTICE "Valid pmd");

    ptep = pte_offset_map(pmd, addr);
    if (!ptep)
        goto out;
    pte = *ptep;

    page = pte_page(pte);
    if (page)
        printk(KERN_INFO "page frame struct is @ %p", page);

 out:
    return page;
}

This function is called from the ioctl and addr is a virtual address in process address space:

static int my_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long addr)
{
   struct page *page = walk_page_table(addr);
   ...
   return 0;
}

The strange thing is that calling ioctl in a user space process, this segfaults...but it seems that the way i'm looking for the page table entry is correct because with dmesg i obtain for example for each ioctl call:

[ 1721.437104] Valid pgd
[ 1721.437108] Valid pud
[ 1721.437108] Valid pmd
[ 1721.437110] page frame struct is @ c17d9b80

So why the process can't complete correcly the `ioctl' call? Maybe i have to lock something before navigating the page tables?

I'm working with kernel 2.6.35-22 and three levels page tables.

Thank you all!


Cgroup memory controller

$
0
0

I have done a simple experiment with both v1 and v2 cgroup memory controller on a 4.18 kernel that looks like this.

  1. I set the maximum memory limit accordingly. For v1 I write into the memory.limit_in_bytes and for v2 I write into the memory.max file.
  2. I move the current bash instance into it (i.e. $$) and start a loop that does only ls. The limit is set to 8M bytes.

    while [[ 1 ]]; do ls; done
    

After a while, the bash instance is terminated due to OOM. I do not understand why is this the case because the ls process will return the memory after it finishes so that it can be reused in the next iteration.

I am missing something?

Thanks,

Kernel Oops page fault error codes for ARM

$
0
0

What does error code after Oops give information about the panic in arm ex. Oops: 17 [#1] PREEMPT SMP what 17 give information in this case. In x86 it represents -

  • bit 0 == 0: no page found 1: protection fault

  • bit 1 == 0: read access 1: write access

  • bit 2 == 0: kernel-mode access 1: user-mode access

  • bit 3 == 1: use of reserved bit detected

  • bit 4 == 1: fault was an instruction fetch

But i am not able to find any information in arm.

Thanks Shunty

How do I use ioctl() to manipulate my kernel module?

$
0
0

So I'm trying to write a kernel module that uses the linux/timer.h file. I got it to work inside just the module, and now I am trying to get it to work from a user program.

Here is my kernel module:

//Necessary Includes For Device Drivers.
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <linux/timer.h>
#include <linux/ioctl.h>

#define DEVICE_NAME "mytimer"
#define DEVICE_FILE_NAME "mytimer"
#define MAJOR_NUM 61
#define MINOR_NUM 0

MODULE_LICENSE("Dual BSD/GPL");

static struct timer_list my_timer;

struct file_operations FileOps = 
{
    //No File Operations for this timer.
};

//Function to perform when timer expires.
void TimerExpire(int data)
{
    printk("Timer Data: %d\n", data);
}

//Function to set up timers.
void TimerSetup(void)
{
    setup_timer(&my_timer, TimerExpire, 5678);
    mod_timer(&my_timer, jiffies + msecs_to_jiffies(5000));
}

//Module Init and Exit Functions.
int init_module(void)
{
    int initResult = register_chrdev(MAJOR_NUM, "mytimer", &FileOps);

    if (initResult < 0)
    {
        printk("Cannot obtain major number %d\n", MAJOR_NUM);

        return initResult;
    }

printk("Loading MyTimer Kernel Module...\n");


return 0;
}
void cleanup_module(void)
{
    unregister_chrdev(MAJOR_NUM, "mytimer");
    printk("Unloading MyTimer Kernel Module...\n");
}

More specifically, I want my user program to call the TimerSetup() function. I know that I'll need to use ioctl() but I'm not sure how to specify in my MODULE FILE that TimerSetup() should be callable via ioctl().

Also, my second question: I was able to insmod my module and also mknod into /dev/mytimer with the correct major number. But when I tried to open() it so that I can get the file descriptor from it, it kept returning -1, which I'm assuming is wrong. I made sure the permissions were fine (in fact, I made it 777 just to be sure)... It still doesn't work... Is there something I'm missing?

Here is the user program just in case:

#include <stdio.h>

int main(int argc, char* argv[])
{
    int fd = open("/dev/mytimer", "r");
    printf("fd: %d\n", fd);

    return 0;
}

How the util of iostat is computed?

$
0
0
iostat -x -d 

can display many i/o statistic info. For util of iostat, the explanation is :

Percentage of CPU time during which I/O requests were issued to the device (band-width utilization for the device). Device saturation occurs when this value is close to 100%

I want to know how the util was computed?

I make an experiment, (see following code), start 40 thread to randomly read 40 files. I suppose the disk util should be very high, but I am wrong, the iostat is as follow, anyone can give why? THX

Device:         rrqm/s   wrqm/s   r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sdb1              0.01     0.44  0.24  0.57     3.44     8.14    14.34     0.00    2.28   0.66   0.05

Code:

#include <iostream>
#include <fstream>
#include <pthread.h>

using namespace std;

void* work(void* a)
{
    int* id = (int*)a;
    string file = "sys.partition";
    char buf[100];
    sprintf(buf, "%d", *id);
    file.append(string(buf));
    ifstream in(file.c_str());
    in.seekg(0, ios_base::end);
    size_t len = in.tellg();

    cout << "open file : "<< file << " , "<< len << endl;
    srand(time(NULL));

    while(true)
    {
        size_t pos = rand() % len;
        in.seekg(pos);
        //cout << pos << endl;
        in.read(buf, 10);
        system("sync");
    }
    in.close();
}

int main(int argc, char** argv)
{
    static const int num = 40;
    pthread_t threads[num];
    for (int i = 0; i < num; i++)       {
        pthread_create(&threads[i], NULL, work, &i);
    }
    for (int i = 0; i < num; i++)       {
        pthread_join(threads[i], NULL);
    }
    return 0;
}

Restrict folder access via ssh [closed]

Viewing all 12211 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>