kernel newbie here...
I'm trying to do a swapoff from inside kernel code (on a swap device at a known location, suitable for hardcoding). I found the syscall sys_swapoff, which looks fairly straigtforward, so I tried just doing:
sys_swapoff("/path/to/swap/device");
but that doesn't work (it returns error 开发者_如何学JAVAno -14). Using ghetto-style debugging via printk, I've determined that it's erroring out on this codeblock in sys_swapoff:
pathname = getname(specialfile);
err = PTR_ERR(pathname);
if (IS_ERR(pathname))
goto out;
So apparently it doesn't like something about the pathname I'm giving it. I thought maybe it was because I was passing it a string literal instead of an allocated buffer, so I tried kmallocing a buffer, strcpying the path into it, and passing it that, but that made no difference. What am I doing wrong? Is there a better way to do a swapoff from inside kernel code other than using the syscall?
Are you specifying the path to the specific numbered partition (e.g. sda1 vs sda) as part of your path? Can you provide the specific value you used?
Actually, if you're trying to do this inside kernel code -- sys_swapoff expects the parameter being passed in to be from userspace, so you probably need to decompose sys_swapoff and do some of that work yourself in your code.
There's existing code in the TuxOnIce patch set (widely used for hibernation support in various Linux distros) that enables / disables swap when needed, i.e. when creating a hibernation image and/or resuming.
What this code does (check kernel/power/tuxonice_swap.c
in the patch sources) is exactly the same as you do - sys_swapoff(swapfilename);
- and it's functional. So there's nothing wrong with the invocation from kernel space as such.
How sure are you about your device pathname ? Have you instrumented sys_swapon()
and sys_swapoff()
so that they print what is actually passed when you manually on the command line issue swapon
/ swapoff
commands ? udev
& friends and/or the usage of initramfs
sometimes result in device pathnames that aren't universally valid.
Edit:
Since you just stated in a comment you're attempting /dev/block/...
- that might well be your cause; the path is an artifact, just after boot these device nodes exist directly in /dev/
(like /dev/mmcblk0
becomes /dev/block/mmcblk0
later). Try /dev/zram0
and see what happens.
精彩评论