// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2022 Google, Inc. All Rights Reserved. * * Test program which uses the raw ext4 set_fsuuid ioctl directly. * SYNOPSIS: * $0 COMMAND MOUNT_POINT [UUID] * * COMMAND must be either "get" or "set". * The UUID must be a 16 octet sequence represented as 32 hexadecimal digits in * canonical textual representation, e.g. output from `uuidgen`. * */ #include #include #include #include #include #include #include #include #include #include struct fsuuid { __u32 fsu_len; __u32 fsu_flags; __u8 fsu_uuid[]; }; #ifndef EXT4_IOC_GETFSUUID #define EXT4_IOC_GETFSUUID _IOR('f', 44, struct fsuuid) #endif #ifndef EXT4_IOC_SETFSUUID #define EXT4_IOC_SETFSUUID _IOW('f', 44, struct fsuuid) #endif int main(int argc, char **argv) { int error, fd; struct fsuuid *fsuuid = NULL; if (argc < 3) { fprintf(stderr, "Invalid arguments\n"); return 1; } fd = open(argv[2], O_RDONLY); if (!fd) { perror(argv[2]); return 1; } fsuuid = malloc(sizeof(*fsuuid) + sizeof(uuid_t)); if (!fsuuid) { perror("malloc"); return 1; } fsuuid->fsu_len = sizeof(uuid_t); fsuuid->fsu_flags = 0; if (strcmp(argv[1], "get") == 0) { uuid_t uuid; char uuid_str[37]; if (ioctl(fd, EXT4_IOC_GETFSUUID, fsuuid)) { fprintf(stderr, "%s while trying to get fs uuid\n", strerror(errno)); return 1; } memcpy(&uuid, fsuuid->fsu_uuid, sizeof(uuid)); uuid_unparse(uuid, uuid_str); printf("%s\n", uuid_str); } else if (strcmp(argv[1], "set") == 0) { uuid_t uuid; if (argc != 4) { fprintf(stderr, "UUID argument missing.\n"); return 1; } error = uuid_parse(argv[3], uuid); if (error < 0) { fprintf(stderr, "Invalid UUID. The UUID should be in " "canonical format. Example: " "8c628557-6987-42b2-ba16-b7cc79ddfb43\n"); return 1; } memcpy(&fsuuid->fsu_uuid, uuid, sizeof(uuid)); if (ioctl(fd, EXT4_IOC_SETFSUUID, fsuuid)) { fprintf(stderr, "%s while trying to set fs uuid\n", strerror(errno)); return 1; } } else { fprintf(stderr, "Invalid command\n"); return 1; } return 0; }