我想用普通用户(非root用户)在systemd上运行我的程序。该程序使用ioctl()系统调用来访问emmc寄存器。我想了解哪些功能需要添加到我的systemd单元文件中。
我尝试了以下单位文件:
[Unit]
Description=EMMC-LIFETIME UTILITY
[Service]
User=tron
Group=disk
ExecStart=/HARICI/emmc-lifetime /dev/mmcblk0 -v
CapabilityBoundingSet=CAP_SYS_ADMIN
DeviceAllow=/dev/mmcblk0 rw
[Install]
WantedBy=multi-user.target
这是emmc-lifetime的代码:
int main(int argc, char **argv)
{
if(argc < 2){
printf("Usage: %s <mmcfilename> (-v)\n", argv[0]);
printf("Example: %s /dev/mmcblk1 -v\n", argv[0]);
return 1;
}
char ext_csd[512], ext_csd_rev;
int fd, ret;
fd = open(argv[1], O_RDWR);
if (fd < 0) {
printf("Failed to open eMMC device, please check which path you have passed\n");
return 1;
}
struct mmc_ioc_cmd idata;
memset(&idata, 0, sizeof(idata));
memset(ext_csd, 0, sizeof(char) * 512);
idata.write_flag = 0;
idata.opcode = MMC_SEND_EXT_CSD;
idata.arg = 0;
idata.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
idata.blksz = 512;
idata.blocks = 1;
mmc_ioc_cmd_set_data(idata, ext_csd);
ret = ioctl(fd, MMC_IOC_CMD, &idata);
if (ret){
printf("ioctl failed, are you sure it is an MMC device???\n");
return ret;
}
ext_csd_rev = ext_csd[EXT_CSD_REV];
if (ext_csd_rev >= 7) {
if(argc==3 && !strcmp(argv[2],"-v")){
printf("EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A: 0x%02x\n",
ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]);
printf("EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B: 0x%02x\n",
ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B]);
printf("EXT_CSD_PRE_EOL_INFO: 0x%02x\n",
ext_csd[EXT_CSD_PRE_EOL_INFO]);
}else{
printf("%d\n",ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B]*10);
}
}
if(fd)
close(fd);
return ret;
如果我在单元文件中将“ User = tron”注释掉,那么一切都会正常进行:
Nov 03 01:17:03 tron systemd[1]: Started EMMC-LIFETIME UTILITY.
Nov 03 01:17:03 tron emmc-lifetime[28294]: EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A: 0x01
Nov 03 01:17:03 tron emmc-lifetime[28294]: EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B: 0x01
Nov 03 01:17:03 tron emmc-lifetime[28294]: EXT_CSD_PRE_EOL_INFO: 0x01
但是如果我取消注释“ User = tron”,结果如下:
Nov 03 00:57:17 tron systemd[1]: Started EMMC-LIFETIME UTILITY.
Nov 03 00:57:17 tron emmc-lifetime[27706]: ioctl failed, are you sure it is an MMC device???
Nov 03 00:57:17 tron systemd[1]: emmc-info.service: Main process exited, code=exited, status=255/n/a
Nov 03 00:57:18 tron systemd[1]: emmc-info.service: Unit entered failed state.
Nov 03 00:57:18 tron systemd[1]: emmc-info.service: Failed with result 'exit-code'.
我的单位文件中具有什么功能才能以“ tron”用户身份运行我的可执行文件?
已解决。对于功能方面,它必须具有CAP_SYS_RAWIO。
我们可以使用:
setcap cap_sys_rawio=+eip /HARICI/emmc-lifetime
并且通过这种方式,我们可以用非root用户运行“ emmc-lifetime”二进制文件。请注意,该用户必须在“磁盘”组中才能打开“ / dev / mmcblkX”
但是很遗憾,这在systemd单位文件中不起作用。
在系统单位文件中,如果您编写:
User=some-non-root-user
CapabilityBoundingSet=SOME_CAPABILITY
不起作用。这就是为什么我的上述代码始终失败的原因。
我必须找到另一种以非root用户特权运行二进制文件的方法。