【问题标题】:linux kernel module data compressionlinux内核模块数据压缩
【发布时间】:2018-03-03 13:41:33
【问题描述】:

Linux 2.6 我正在写一个 LKM。我需要即时压缩和解压缩许多不同的文本块。

我更喜欢调用内核api,避免包含和编译外部库。

是否有内核 Api 来压缩和解压缩内存? 源缓冲区和目标缓冲区可以都在内核内存中,也可以一个在内核中,另一个在用户空间中。

【问题讨论】:

标签: linux kernel compression


【解决方案1】:

不知道为什么kernel.org 不包括压缩部分。

可能需要模仿官方skcipher的例子,过程如下:

tfm = crypto_alloc_tfm("yourAlg",
                       CRYPTO_TFM_MODE_yourAlg);
req = skcipher_request_alloc(tfm, GFP_KERNEL);
skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                  test_tfm_cb,
                  result);
crypto_cipher_setkey(tfm, key, keylength);
crypto_cipher_encrypt(tfm, &scatterlist,
                      numlists);
tfm_request_free(req);
crypto_free_tfm(tfm);

注意内核现在正在转向异步,但是最新的header 文件中没有显示回调。

/**
 * acomp_request_set_callback() -- Sets an asynchronous callback
 *
 * Callback will be called when an asynchronous operation on a given
 * request is finished.
 *
 * @req:        request that the callback will be set for
 * @flgs:       specify for instance if the operation may backlog
 * @cmlp:       callback which will be called
 * @data:       private data used by the caller
 */
static inline void acomp_request_set_callback(struct acomp_req *req,
                                              u32 flgs,
                                              crypto_completion_t cmpl,
                                              void *data)
{
        req->base.complete = cmpl;
        req->base.data = data;
        req->base.flags = flgs;
}

示例代码:

    struct comp_testvec tv, int mode;
    int ilen = tv.inlen;    
    char *str_input = tv.input;
    int olen = tv.outlen;
    char *str_output = tv.output;

    struct scatterlist sg[2];
    struct scatterlist sg2[2];
    char *input;
    char *output;
    char *input2;
    char *output2;
    struct acomp_req *req;
    struct crypto_acomp *tfm;
    struct tcrypt_result result;
    int ret = 0;

    input = kmalloc(ilen, GFP_KERNEL);
    output = kmalloc(olen, GFP_KERNEL);
    input2 = kmalloc(olen, GFP_KERNEL);
    output2 = kmalloc(ilen, GFP_KERNEL);


    char *driver = tv.alg;
    tfm = crypto_alloc_acomp(driver, CRYPTO_ALG_TYPE_ACOMPRESS,
                   CRYPTO_ALG_TYPE_ACOMPRESS_MASK);
    if (IS_ERR(tfm)) {
        printk(KERN_ERR "alg: acomp: Failed to load transform for "
               "%s: %ld\n", driver, PTR_ERR(tfm));
        return PTR_ERR(tfm);
    }

    init_completion(&result.completion);


if (mode == 0)
{
    //zip
    memcpy(input,str_input,ilen);
    printk("input => %s\n", input);    
    print_hex_dump(KERN_CONT, "| ", DUMP_PREFIX_OFFSET, 16, 1, input, ilen, false);

    printk("alg => %s\n",driver);

    sg_init_one(&sg[0], input, ilen);
    sg_init_one(&sg[1], output, COMP_BUF_SIZE);

    req = acomp_request_alloc(tfm);
    if(!req)
    {
        printk("error req = null\n");
        crypto_free_acomp(tfm);
        return -1;  
    }
    acomp_request_set_params(req, &sg[0], &sg[1], ilen, COMP_BUF_SIZE);
    acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                       tcrypt_complete, &result);

    ret = crypto_acomp_compress(req);

    if(ret == -EINPROGRESS || ret == -EBUSY)
    {
        ret = wait_for_completion_interruptible(
            &result.completion);
        if (!ret && !((ret = result.err)))
        {
            reinit_completion(&result.completion);
        }
    }
    else if(ret  == 0)
    {
        printk("succ\n");
    }
    else
    {
        printk("error ret = %d\n",ret);
        goto out;
    }
    printk("compress => \n");
    print_hex_dump(KERN_CONT, "| ", DUMP_PREFIX_OFFSET, 16, 1, output, olen, false);

} else if (mode == 1) {
//unzip
    memcpy(input2,str_output,olen);
    printk("input => \n");    
    print_hex_dump(KERN_CONT, "| ", DUMP_PREFIX_OFFSET, 16, 1, input2, olen, false);

    char *driver = tv.alg;
    printk("alg => %s\n",driver);

      //sg init
    sg_init_one(&sg2[0], input2, ilen);
    sg_init_one(&sg2[1], output2, COMP_BUF_SIZE);

    req = acomp_request_alloc(tfm);
    if(!req)
    {
        printk("error req = null\n");
        crypto_free_acomp(tfm);
        return -1;  
    }
    acomp_request_set_params(req, &sg2[0], &sg2[1], ilen, COMP_BUF_SIZE);
    acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                       tcrypt_complete, &result);

    ret = crypto_acomp_decompress(req);

    if(ret == -EINPROGRESS || ret == -EBUSY)
    {
        ret = wait_for_completion_interruptible(
            &result.completion);
        if (!ret && !((ret = result.err)))
        {
            reinit_completion(&result.completion);
        }
    }
    else if(ret  == 0)
    {
        printk("succ\n");
    }
    else
    {
        printk("error ret = %d\n",ret);
        goto out;
    }
    printk("decompress => %s\n", output2);
    print_hex_dump(KERN_CONT, "| ", DUMP_PREFIX_OFFSET, 16, 1, output2, ilen, false);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-11
    • 2013-12-17
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 2016-03-25
    • 2015-09-21
    相关资源
    最近更新 更多