generic: test MADV_POPULATE_READ with IO errors
[xfstests-dev.git] / src / uuid_ioctl.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2022 Google, Inc. All Rights Reserved.
4  *
5  * Test program which uses the raw ext4 set_fsuuid ioctl directly.
6  * SYNOPSIS:
7  *   $0 COMMAND MOUNT_POINT [UUID]
8  *
9  * COMMAND must be either "get" or "set".
10  * The UUID must be a 16 octet sequence represented as 32 hexadecimal digits in
11  * canonical textual representation, e.g. output from `uuidgen`.
12  *
13  */
14
15 #include <stdio.h>
16 #include <fcntl.h>
17 #include <errno.h>
18 #include <unistd.h>
19 #include <stdint.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <sys/ioctl.h>
23 #include <uuid/uuid.h>
24 #include <linux/fs.h>
25
26 struct fsuuid {
27         __u32   fsu_len;
28         __u32   fsu_flags;
29         __u8    fsu_uuid[];
30 };
31
32 #ifndef EXT4_IOC_GETFSUUID
33 #define EXT4_IOC_GETFSUUID      _IOR('f', 44, struct fsuuid)
34 #endif
35
36 #ifndef EXT4_IOC_SETFSUUID
37 #define EXT4_IOC_SETFSUUID      _IOW('f', 44, struct fsuuid)
38 #endif
39
40 int main(int argc, char **argv)
41 {
42         int error, fd;
43         struct fsuuid *fsuuid = NULL;
44
45         if (argc < 3) {
46                 fprintf(stderr, "Invalid arguments\n");
47                 return 1;
48         }
49
50         fd = open(argv[2], O_RDONLY);
51         if (!fd) {
52                 perror(argv[2]);
53                 return 1;
54         }
55
56         fsuuid = malloc(sizeof(*fsuuid) + sizeof(uuid_t));
57         if (!fsuuid) {
58                 perror("malloc");
59                 return 1;
60         }
61         fsuuid->fsu_len = sizeof(uuid_t);
62         fsuuid->fsu_flags = 0;
63
64         if (strcmp(argv[1], "get") == 0) {
65                 uuid_t uuid;
66                 char uuid_str[37];
67
68                 if (ioctl(fd, EXT4_IOC_GETFSUUID, fsuuid)) {
69                         fprintf(stderr, "%s while trying to get fs uuid\n",
70                                 strerror(errno));
71                         return 1;
72                 }
73
74                 memcpy(&uuid, fsuuid->fsu_uuid, sizeof(uuid));
75                 uuid_unparse(uuid, uuid_str);
76                 printf("%s\n", uuid_str);
77         } else if (strcmp(argv[1], "set") == 0) {
78                 uuid_t uuid;
79
80                 if (argc != 4) {
81                         fprintf(stderr, "UUID argument missing.\n");
82                         return 1;
83                 }
84
85                 error = uuid_parse(argv[3], uuid);
86                 if (error < 0) {
87                         fprintf(stderr, "Invalid UUID. The UUID should be in "
88                                 "canonical format. Example: "
89                                 "8c628557-6987-42b2-ba16-b7cc79ddfb43\n");
90                         return 1;
91                 }
92
93                 memcpy(&fsuuid->fsu_uuid, uuid, sizeof(uuid));
94                 if (ioctl(fd, EXT4_IOC_SETFSUUID, fsuuid)) {
95                         fprintf(stderr, "%s while trying to set fs uuid\n",
96                                 strerror(errno));
97                         return 1;
98                 }
99         } else {
100                 fprintf(stderr, "Invalid command\n");
101                 return 1;
102         }
103
104         return 0;
105 }