source: branches/3.2/mindi-busybox/util-linux/blockdev.c @ 3232

Last change on this file since 3232 was 3232, checked in by bruno, 5 years ago
  • Update mindi-busybox to 1.21.1
  • Property svn:eol-style set to native
File size: 4.5 KB
Line 
1/*
2 * blockdev implementation for busybox
3 *
4 * Copyright (C) 2010 Sergey Naumov <sknaumov@gmail.com>
5 *
6 * Licensed under GPLv2, see file LICENSE in this source tree.
7 */
8
9//applet:IF_BLOCKDEV(APPLET(blockdev, BB_DIR_SBIN, BB_SUID_DROP))
10
11//kbuild:lib-$(CONFIG_BLOCKDEV) += blockdev.o
12
13//config:config BLOCKDEV
14//config:   bool "blockdev"
15//config:   default y
16//config:   help
17//config:     Performs some ioctls with block devices.
18
19//usage:#define blockdev_trivial_usage
20//usage:    "OPTION BLOCKDEV"
21//usage:#define blockdev_full_usage "\n\n"
22//usage:       "    --setro     Set ro"
23//usage:     "\n    --setrw     Set rw"
24//usage:     "\n    --getro     Get ro"
25//usage:     "\n    --getss     Get sector size"
26//usage:     "\n    --getbsz    Get block size"
27//usage:     "\n    --setbsz BYTES  Set block size"
28//usage:     "\n    --getsz     Get device size in 512-byte sectors"
29/*//usage:     "\n  --getsize   Get device size in sectors (deprecated)"*/
30//usage:     "\n    --getsize64 Get device size in bytes"
31//usage:     "\n    --flushbufs Flush buffers"
32//usage:     "\n    --rereadpt  Reread partition table"
33
34
35#include "libbb.h"
36#include <linux/fs.h>
37
38enum {
39    ARG_NONE   = 0,
40    ARG_INT    = 1,
41    ARG_ULONG  = 2,
42    /* Yes, BLKGETSIZE64 takes pointer to uint64_t, not ullong! */
43    ARG_U64    = 3,
44    ARG_MASK   = 3,
45
46    FL_USRARG   = 4, /* argument is provided by user */
47    FL_NORESULT = 8,
48    FL_SCALE512 = 16,
49};
50
51struct bdc {
52    uint32_t   ioc;                       /* ioctl code */
53    const char name[sizeof("flushbufs")]; /* "--setfoo" wothout "--" */
54    uint8_t    flags;
55    int8_t     argval;                    /* default argument value */
56};
57
58static const struct bdc bdcommands[] = {
59    {
60        .ioc = BLKROSET,
61        .name = "setro",
62        .flags = ARG_INT + FL_NORESULT,
63        .argval = 1,
64    },{
65        .ioc = BLKROSET,
66        .name = "setrw",
67        .flags = ARG_INT + FL_NORESULT,
68        .argval = 0,
69    },{
70        .ioc = BLKROGET,
71        .name = "getro",
72        .flags = ARG_INT,
73        .argval = -1,
74    },{
75        .ioc = BLKSSZGET,
76        .name = "getss",
77        .flags = ARG_INT,
78        .argval = -1,
79    },{
80        .ioc = BLKBSZGET,
81        .name = "getbsz",
82        .flags = ARG_INT,
83        .argval = -1,
84    },{
85        .ioc = BLKBSZSET,
86        .name = "setbsz",
87        .flags = ARG_INT + FL_NORESULT + FL_USRARG,
88        .argval = 0,
89    },{
90        .ioc = BLKGETSIZE64,
91        .name = "getsz",
92        .flags = ARG_U64 + FL_SCALE512,
93        .argval = -1,
94    },{
95        .ioc = BLKGETSIZE,
96        .name = "getsize",
97        .flags = ARG_ULONG,
98        .argval = -1,
99    },{
100        .ioc = BLKGETSIZE64,
101        .name = "getsize64",
102        .flags = ARG_U64,
103        .argval = -1,
104    },{
105        .ioc = BLKFLSBUF,
106        .name = "flushbufs",
107        .flags = ARG_NONE + FL_NORESULT,
108        .argval = 0,
109    },{
110        .ioc = BLKRRPART,
111        .name = "rereadpt",
112        .flags = ARG_NONE + FL_NORESULT,
113        .argval = 0,
114    }
115};
116
117static const struct bdc *find_cmd(const char *s)
118{
119    const struct bdc *bdcmd = bdcommands;
120    if (s[0] == '-' && s[1] == '-') {
121        s += 2;
122        do {
123            if (strcmp(s, bdcmd->name) == 0)
124                return bdcmd;
125            bdcmd++;
126        } while (bdcmd != bdcommands + ARRAY_SIZE(bdcommands));
127    }
128    bb_show_usage();
129}
130
131int blockdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
132int blockdev_main(int argc UNUSED_PARAM, char **argv)
133{
134    const struct bdc *bdcmd;
135    int fd;
136    uint64_t u64;
137    union {
138        int i;
139        unsigned long lu;
140        uint64_t u64;
141    } ioctl_val_on_stack;
142
143    argv++;
144    if (!argv[0] || !argv[1]) /* must have at least 2 args */
145        bb_show_usage();
146
147    bdcmd = find_cmd(*argv);
148
149    u64 = (int)bdcmd->argval;
150    if (bdcmd->flags & FL_USRARG)
151        u64 = xatoi_positive(*++argv);
152
153    argv++;
154    if (!argv[0] || argv[1])
155        bb_show_usage();
156    fd = xopen(argv[0], O_RDONLY);
157
158    ioctl_val_on_stack.u64 = u64;
159#if BB_BIG_ENDIAN
160    /* Store data properly wrt data size.
161     * (1) It's no-op for little-endian.
162     * (2) it's no-op for 0 and -1. Only --setro uses arg != 0 and != -1,
163     * and it is ARG_INT. --setbsz USER_VAL is also ARG_INT.
164     * Thus, we don't need to handle ARG_ULONG.
165     */
166    switch (bdcmd->flags & ARG_MASK) {
167    case ARG_INT:
168        ioctl_val_on_stack.i = (int)u64;
169        break;
170# if 0 /* unused */
171    case ARG_ULONG:
172        ioctl_val_on_stack.lu = (unsigned long)u64;
173        break;
174# endif
175    }
176#endif
177
178    if (ioctl(fd, bdcmd->ioc, &ioctl_val_on_stack.u64) == -1)
179        bb_simple_perror_msg_and_die(*argv);
180
181    /* Fetch it into register(s) */
182    u64 = ioctl_val_on_stack.u64;
183
184    if (bdcmd->flags & FL_SCALE512)
185        u64 >>= 9;
186
187    /* Zero- or one-extend the value if needed, then print */
188    switch (bdcmd->flags & (ARG_MASK+FL_NORESULT)) {
189    case ARG_INT:
190        /* Smaller code when we use long long
191         * (gcc tail-merges printf call)
192         */
193        printf("%lld\n", (long long)(int)u64);
194        break;
195    case ARG_ULONG:
196        u64 = (unsigned long)u64;
197        /* FALLTHROUGH */
198    case ARG_U64:
199        printf("%llu\n", (unsigned long long)u64);
200        break;
201    }
202
203    if (ENABLE_FEATURE_CLEAN_UP)
204        close(fd);
205    return EXIT_SUCCESS;
206}
Note: See TracBrowser for help on using the repository browser.