]> git.ipfire.org Git - thirdparty/util-linux.git/blame - sys-utils/zramctl.c
misc: consolidate macro style USAGE_HELP_OPTIONS
[thirdparty/util-linux.git] / sys-utils / zramctl.c
CommitLineData
0624d840 1/*
1c35e625 2 * zramctl - control compressed block devices in RAM
0624d840
KZ
3 *
4 * Copyright (c) 2014 Timofey Titovets <Nefelim4ag@gmail.com>
5 * Copyright (C) 2014 Karel Zak <kzak@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it would be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#include <getopt.h>
22#include <stdlib.h>
23#include <string.h>
24#include <stdarg.h>
25#include <assert.h>
26
27#include <libsmartcols.h>
28
29#include "c.h"
30#include "nls.h"
31#include "closestream.h"
32#include "strutils.h"
33#include "xalloc.h"
34#include "sysfs.h"
35#include "optutils.h"
36#include "ismounted.h"
5388c862 37#include "strv.h"
1ceb4077 38#include "path.h"
62725810 39#include "pathnames.h"
0624d840
KZ
40
41/*#define CONFIG_ZRAM_DEBUG*/
42
43#ifdef CONFIG_ZRAM_DEBUG
44# define DBG(x) do { fputs("zram: ", stderr); x; fputc('\n', stderr); } while(0)
45#else
46# define DBG(x)
47#endif
48
49/* status output columns */
50struct colinfo {
51 const char *name;
52 double whint;
53 int flags;
54 const char *help;
55};
56
57enum {
58 COL_NAME = 0,
59 COL_DISKSIZE,
60 COL_ORIG_SIZE,
61 COL_COMP_SIZE,
62 COL_ALGORITHM,
63 COL_STREAMS,
64 COL_ZEROPAGES,
65 COL_MEMTOTAL,
bffc9174
KZ
66 COL_MEMLIMIT,
67 COL_MEMUSED,
68 COL_MIGRATED,
0624d840
KZ
69 COL_MOUNTPOINT
70};
71
72static const struct colinfo infos[] = {
73 [COL_NAME] = { "NAME", 0.25, 0, N_("zram device name") },
1c35e625 74 [COL_DISKSIZE] = { "DISKSIZE", 5, SCOLS_FL_RIGHT, N_("limit on the uncompressed amount of data") },
0624d840
KZ
75 [COL_ORIG_SIZE] = { "DATA", 5, SCOLS_FL_RIGHT, N_("uncompressed size of stored data") },
76 [COL_COMP_SIZE] = { "COMPR", 5, SCOLS_FL_RIGHT, N_("compressed size of stored data") },
1c35e625 77 [COL_ALGORITHM] = { "ALGORITHM", 3, 0, N_("the selected compression algorithm") },
0624d840
KZ
78 [COL_STREAMS] = { "STREAMS", 3, SCOLS_FL_RIGHT, N_("number of concurrent compress operations") },
79 [COL_ZEROPAGES] = { "ZERO-PAGES", 3, SCOLS_FL_RIGHT, N_("empty pages with no allocated memory") },
80 [COL_MEMTOTAL] = { "TOTAL", 5, SCOLS_FL_RIGHT, N_("all memory including allocator fragmentation and metadata overhead") },
bffc9174 81 [COL_MEMLIMIT] = { "MEM-LIMIT", 5, SCOLS_FL_RIGHT, N_("memory limit used to store compressed data") },
1ab7abac 82 [COL_MEMUSED] = { "MEM-USED", 5, SCOLS_FL_RIGHT, N_("memory zram have been consumed to store compressed data") },
75a8e726 83 [COL_MIGRATED] = { "MIGRATED", 5, SCOLS_FL_RIGHT, N_("number of objects migrated by compaction") },
0624d840 84 [COL_MOUNTPOINT]= { "MOUNTPOINT",0.10, SCOLS_FL_TRUNC, N_("where the device is mounted") },
0624d840
KZ
85};
86
87static int columns[ARRAY_SIZE(infos) * 2] = {-1};
88static int ncolumns;
89
5388c862
KZ
90enum {
91 MM_ORIG_DATA_SIZE = 0,
92 MM_COMPR_DATA_SIZE,
93 MM_MEM_USED_TOTAL,
94 MM_MEM_LIMIT,
95 MM_MEM_USED_MAX,
96 MM_ZERO_PAGES,
97 MM_NUM_MIGRATED
98};
99
100static const char *mm_stat_names[] = {
101 [MM_ORIG_DATA_SIZE] = "orig_data_size",
102 [MM_COMPR_DATA_SIZE] = "compr_data_size",
103 [MM_MEM_USED_TOTAL] = "mem_used_total",
104 [MM_MEM_LIMIT] = "mem_limit",
105 [MM_MEM_USED_MAX] = "mem_used_max",
106 [MM_ZERO_PAGES] = "zero_pages",
107 [MM_NUM_MIGRATED] = "num_migrated"
108};
109
110
0624d840
KZ
111struct zram {
112 char devname[32];
113 struct sysfs_cxt sysfs;
5388c862
KZ
114 char **mm_stat;
115
62725810
KZ
116 unsigned int mm_stat_probed : 1,
117 control_probed : 1,
118 has_control : 1; /* has /sys/class/zram-control/ */
0624d840
KZ
119};
120
121#define ZRAM_EMPTY { .devname = { '\0' }, .sysfs = UL_SYSFSCXT_EMPTY }
122
123static unsigned int raw, no_headings, inbytes;
124
125
126static int get_column_id(int num)
127{
128 assert(num < ncolumns);
129 assert(columns[num] < (int) ARRAY_SIZE(infos));
130 return columns[num];
131}
132
133static const struct colinfo *get_column_info(int num)
134{
135 return &infos[ get_column_id(num) ];
136}
137
138static int column_name_to_id(const char *name, size_t namesz)
139{
140 size_t i;
141
142 for (i = 0; i < ARRAY_SIZE(infos); i++) {
143 const char *cn = infos[i].name;
144
145 if (!strncasecmp(name, cn, namesz) && !*(cn + namesz))
146 return i;
147 }
148 warnx(_("unknown column: %s"), name);
149 return -1;
150}
151
1ceb4077
KZ
152static void zram_reset_stat(struct zram *z)
153{
154 if (z) {
155 strv_free(z->mm_stat);
156 z->mm_stat = NULL;
157 z->mm_stat_probed = 0;
158 }
159}
160
0624d840
KZ
161static void zram_set_devname(struct zram *z, const char *devname, size_t n)
162{
163 assert(z);
164
165 if (!devname)
166 snprintf(z->devname, sizeof(z->devname), "/dev/zram%zu", n);
167 else {
168 strncpy(z->devname, devname, sizeof(z->devname));
169 z->devname[sizeof(z->devname) - 1] = '\0';
170 }
171
172 DBG(fprintf(stderr, "set devname: %s", z->devname));
173 sysfs_deinit(&z->sysfs);
1ceb4077 174 zram_reset_stat(z);
0624d840
KZ
175}
176
62725810
KZ
177static int zram_get_devnum(struct zram *z)
178{
179 int n;
180
181 assert(z);
182
183 if (sscanf(z->devname, "/dev/zram%d", &n) == 1)
184 return n;
185 return -EINVAL;
186}
187
0624d840
KZ
188static struct zram *new_zram(const char *devname)
189{
190 struct zram *z = xcalloc(1, sizeof(struct zram));
191
192 DBG(fprintf(stderr, "new: %p", z));
193 if (devname)
194 zram_set_devname(z, devname, 0);
195 return z;
196}
197
198static void free_zram(struct zram *z)
199{
200 if (!z)
201 return;
202 DBG(fprintf(stderr, "free: %p", z));
203 sysfs_deinit(&z->sysfs);
1ceb4077 204 zram_reset_stat(z);
0624d840
KZ
205 free(z);
206}
207
208static struct sysfs_cxt *zram_get_sysfs(struct zram *z)
209{
210 assert(z);
211
212 if (!z->sysfs.devno) {
213 dev_t devno = sysfs_devname_to_devno(z->devname, NULL);
214 if (!devno)
215 return NULL;
216 if (sysfs_init(&z->sysfs, devno, NULL))
217 return NULL;
342436c6 218 if (*z->devname != '/') {
9e930041 219 /* canonicalize the device name according to /sys */
342436c6
KZ
220 char name[PATH_MAX];
221 if (sysfs_get_devname(&z->sysfs, name, sizeof(name)))
222 snprintf(z->devname, sizeof(z->devname), "/dev/%s", name);
223 }
0624d840
KZ
224 }
225
226 return &z->sysfs;
227}
228
229static inline int zram_exist(struct zram *z)
230{
231 assert(z);
232
116c9ce2
KZ
233 errno = 0;
234 if (zram_get_sysfs(z) == NULL) {
235 errno = ENODEV;
0624d840 236 return 0;
116c9ce2 237 }
0624d840
KZ
238
239 DBG(fprintf(stderr, "%s exists", z->devname));
240 return 1;
241}
242
243static int zram_set_u64parm(struct zram *z, const char *attr, uint64_t num)
244{
245 struct sysfs_cxt *sysfs = zram_get_sysfs(z);
246 if (!sysfs)
247 return -EINVAL;
248 DBG(fprintf(stderr, "%s writing %ju to %s", z->devname, num, attr));
249 return sysfs_write_u64(sysfs, attr, num);
250}
251
252static int zram_set_strparm(struct zram *z, const char *attr, const char *str)
253{
254 struct sysfs_cxt *sysfs = zram_get_sysfs(z);
255 if (!sysfs)
256 return -EINVAL;
257 DBG(fprintf(stderr, "%s writing %s to %s", z->devname, str, attr));
258 return sysfs_write_string(sysfs, attr, str);
259}
260
261
262static int zram_used(struct zram *z)
263{
264 uint64_t size;
265 struct sysfs_cxt *sysfs = zram_get_sysfs(z);
266
267 if (sysfs &&
268 sysfs_read_u64(sysfs, "disksize", &size) == 0 &&
269 size > 0) {
270
271 DBG(fprintf(stderr, "%s used", z->devname));
272 return 1;
273 }
274 DBG(fprintf(stderr, "%s unused", z->devname));
275 return 0;
276}
277
62725810
KZ
278static int zram_has_control(struct zram *z)
279{
280 if (!z->control_probed) {
281 z->has_control = access(_PATH_SYS_CLASS "/zram-control/", F_OK) == 0 ? 1 : 0;
282 z->control_probed = 1;
283 DBG(fprintf(stderr, "zram-control: %s", z->has_control ? "yes" : "no"));
284 }
285
286 return z->has_control;
287}
288
289static int zram_control_add(struct zram *z)
290{
291 int n;
292
293 if (!zram_has_control(z))
294 return -ENOSYS;
295
296 n = path_read_s32(_PATH_SYS_CLASS "/zram-control/hot_add");
297 if (n < 0)
298 return n;
299
300 DBG(fprintf(stderr, "hot-add: %d", n));
301 zram_set_devname(z, NULL, n);
302 return 0;
303}
304
305static int zram_control_remove(struct zram *z)
306{
307 char str[sizeof stringify_value(INT_MAX)];
308 int n;
309
310 if (!zram_has_control(z))
311 return -ENOSYS;
312
313 n = zram_get_devnum(z);
314 if (n < 0)
315 return n;
316
317 DBG(fprintf(stderr, "hot-remove: %d", n));
318 snprintf(str, sizeof(str), "%d", n);
319 return path_write_str(str, _PATH_SYS_CLASS "/zram-control/hot_remove");
320}
321
0624d840
KZ
322static struct zram *find_free_zram(void)
323{
324 struct zram *z = new_zram(NULL);
325 size_t i;
326 int isfree = 0;
327
328 for (i = 0; isfree == 0; i++) {
329 DBG(fprintf(stderr, "find free: checking zram%zu", i));
330 zram_set_devname(z, NULL, i);
62725810 331 if (!zram_exist(z) && zram_control_add(z) != 0)
0624d840
KZ
332 break;
333 isfree = !zram_used(z);
334 }
335 if (!isfree) {
336 free_zram(z);
337 z = NULL;
338 }
339 return z;
340}
341
624e147b 342static char *get_mm_stat(struct zram *z, size_t idx, int bytes)
5388c862
KZ
343{
344 struct sysfs_cxt *sysfs;
345 const char *name;
346 uint64_t num;
347
348 assert(idx < ARRAY_SIZE(mm_stat_names));
349 assert(z);
350
351 sysfs = zram_get_sysfs(z);
352 if (!sysfs)
353 return NULL;
354
355 /* Linux >= 4.1 uses /sys/block/zram<id>/mm_stat */
356 if (!z->mm_stat && !z->mm_stat_probed) {
357 char *str;
358
359 str = sysfs_strdup(sysfs, "mm_stat");
360 if (str) {
361 z->mm_stat = strv_split(str, " ");
2546d54b
KZ
362
363 /* make sure kernel provides mm_stat as expected */
364 if (strv_length(z->mm_stat) < ARRAY_SIZE(mm_stat_names)) {
365 strv_free(z->mm_stat);
366 z->mm_stat = NULL;
367 }
5388c862
KZ
368 }
369 z->mm_stat_probed = 1;
370 free(str);
371
372 }
373
374 if (z->mm_stat) {
624e147b 375 if (bytes)
5388c862
KZ
376 return xstrdup(z->mm_stat[idx]);
377
378 num = strtou64_or_err(z->mm_stat[idx], _("Failed to parse mm_stat"));
379 return size_to_human_string(SIZE_SUFFIX_1LETTER, num);
380 }
381
382 /* Linux < 4.1 uses /sys/block/zram<id>/<attrname> */
383 name = mm_stat_names[idx];
624e147b 384 if (bytes)
5388c862
KZ
385 return sysfs_strdup(sysfs, name);
386 else if (sysfs_read_u64(sysfs, name, &num) == 0)
387 return size_to_human_string(SIZE_SUFFIX_1LETTER, num);
388 return NULL;
389}
390
0624d840
KZ
391static void fill_table_row(struct libscols_table *tb, struct zram *z)
392{
393 static struct libscols_line *ln;
394 struct sysfs_cxt *sysfs;
395 size_t i;
396 uint64_t num;
397
398 assert(tb);
399 assert(z);
400
401 DBG(fprintf(stderr, "%s: filling status table", z->devname));
402
403 sysfs = zram_get_sysfs(z);
404 if (!sysfs)
405 return;
406
407 ln = scols_table_new_line(tb, NULL);
408 if (!ln)
780ce22c 409 err(EXIT_FAILURE, _("failed to allocate output line"));
0624d840
KZ
410
411 for (i = 0; i < (size_t) ncolumns; i++) {
412 char *str = NULL;
413
414 switch (get_column_id(i)) {
415 case COL_NAME:
416 str = xstrdup(z->devname);
417 break;
418 case COL_DISKSIZE:
419 if (inbytes)
420 str = sysfs_strdup(sysfs, "disksize");
421 else if (sysfs_read_u64(sysfs, "disksize", &num) == 0)
422 str = size_to_human_string(SIZE_SUFFIX_1LETTER, num);
423 break;
0624d840
KZ
424 case COL_ALGORITHM:
425 {
426 char *alg = sysfs_strdup(sysfs, "comp_algorithm");
427 if (!alg)
428 break;
429 if (strstr(alg, "[lzo]") == NULL) {
430 if (strstr(alg, "[lz4]") == NULL)
431 ;
432 else
433 str = xstrdup("lz4");
434 } else
435 str = xstrdup("lzo");
436 free(alg);
437 break;
438 }
439 case COL_MOUNTPOINT:
440 {
441 char path[PATH_MAX] = { '\0' };
442 int fl;
443
444 check_mount_point(z->devname, &fl, path, sizeof(path));
445 if (*path)
446 str = xstrdup(path);
447 break;
448 }
449 case COL_STREAMS:
450 str = sysfs_strdup(sysfs, "max_comp_streams");
451 break;
452 case COL_ZEROPAGES:
5388c862 453 str = get_mm_stat(z, MM_ZERO_PAGES, 1);
0624d840 454 break;
bffc9174
KZ
455 case COL_ORIG_SIZE:
456 str = get_mm_stat(z, MM_ORIG_DATA_SIZE, inbytes);
457 break;
458 case COL_COMP_SIZE:
459 str = get_mm_stat(z, MM_COMPR_DATA_SIZE, inbytes);
460 break;
0624d840 461 case COL_MEMTOTAL:
5388c862 462 str = get_mm_stat(z, MM_MEM_USED_TOTAL, inbytes);
0624d840 463 break;
bffc9174
KZ
464 case COL_MEMLIMIT:
465 str = get_mm_stat(z, MM_MEM_LIMIT, inbytes);
466 break;
467 case COL_MEMUSED:
468 str = get_mm_stat(z, MM_MEM_USED_MAX, inbytes);
469 break;
470 case COL_MIGRATED:
471 str = get_mm_stat(z, MM_NUM_MIGRATED, inbytes);
472 break;
0624d840 473 }
780ce22c 474 if (str && scols_line_refer_data(ln, i, str))
699ad3a1 475 err(EXIT_FAILURE, _("failed to add output data"));
0624d840
KZ
476 }
477}
478
479static void status(struct zram *z)
480{
481 struct libscols_table *tb;
482 size_t i;
483
484 scols_init_debug(0);
485
486 tb = scols_new_table();
487 if (!tb)
780ce22c 488 err(EXIT_FAILURE, _("failed to allocate output table"));
0624d840
KZ
489
490 scols_table_enable_raw(tb, raw);
491 scols_table_enable_noheadings(tb, no_headings);
492
493 for (i = 0; i < (size_t) ncolumns; i++) {
494 const struct colinfo *col = get_column_info(i);
495
496 if (!scols_table_new_column(tb, col->name, col->whint, col->flags))
497 err(EXIT_FAILURE, _("failed to initialize output column"));
498 }
499
500 if (z)
501 fill_table_row(tb, z); /* just one device specified */
502 else {
7ee26cbf 503 /* list all used devices */
0624d840
KZ
504 z = new_zram(NULL);
505
506 for (i = 0; ; i++) {
507 zram_set_devname(z, NULL, i);
508 if (!zram_exist(z))
509 break;
510 if (zram_used(z))
511 fill_table_row(tb, z);
512 }
513 free_zram(z);
514 }
515
516 scols_print_table(tb);
517 scols_unref_table(tb);
518}
519
86be6a32 520static void __attribute__((__noreturn__)) usage(void)
0624d840 521{
86be6a32 522 FILE *out = stdout;
0624d840
KZ
523 size_t i;
524
525 fputs(USAGE_HEADER, out);
526 fprintf(out, _( " %1$s [options] <device>\n"
1c35e625 527 " %1$s -r <device> [...]\n"
0624d840
KZ
528 " %1$s [options] -f | <device> -s <size>\n"),
529 program_invocation_short_name);
530
451dbcfa
BS
531 fputs(USAGE_SEPARATOR, out);
532 fputs(_("Set up and control zram devices.\n"), out);
533
0624d840 534 fputs(USAGE_OPTIONS, out);
1c35e625 535 fputs(_(" -a, --algorithm lzo|lz4 compression algorithm to use\n"), out);
0624d840 536 fputs(_(" -b, --bytes print sizes in bytes rather than in human readable format\n"), out);
1c35e625 537 fputs(_(" -f, --find find a free device\n"), out);
0624d840
KZ
538 fputs(_(" -n, --noheadings don't print headings\n"), out);
539 fputs(_(" -o, --output <list> columns to use for status output\n"), out);
1c35e625 540 fputs(_(" --raw use raw status output format\n"), out);
0624d840
KZ
541 fputs(_(" -r, --reset reset all specified devices\n"), out);
542 fputs(_(" -s, --size <size> device size\n"), out);
423c0d75 543 fputs(_(" -t, --streams <number> number of compression streams\n"), out);
0624d840
KZ
544
545 fputs(USAGE_SEPARATOR, out);
f45f3ec3 546 printf(USAGE_HELP_OPTIONS(27));
0624d840 547
c3a4cfc5 548 fputs(USAGE_COLUMNS, out);
0624d840
KZ
549 for (i = 0; i < ARRAY_SIZE(infos); i++)
550 fprintf(out, " %11s %s\n", infos[i].name, _(infos[i].help));
551
f45f3ec3 552 printf(USAGE_MAN_TAIL("zramctl(8)"));
86be6a32 553 exit(EXIT_SUCCESS);
0624d840
KZ
554}
555
556/* actions */
557enum {
558 A_NONE = 0,
559 A_STATUS,
560 A_CREATE,
561 A_FINDONLY,
562 A_RESET
563};
564
565int main(int argc, char **argv)
566{
567 uintmax_t size = 0, nstreams = 0;
568 char *algorithm = NULL;
569 int rc = 0, c, find = 0, act = A_NONE;
570 struct zram *zram = NULL;
571
572 enum { OPT_RAW = CHAR_MAX + 1 };
573
574 static const struct option longopts[] = {
575 { "algorithm", required_argument, NULL, 'a' },
1c35e625 576 { "bytes", no_argument, NULL, 'b' },
0624d840
KZ
577 { "find", no_argument, NULL, 'f' },
578 { "help", no_argument, NULL, 'h' },
0624d840
KZ
579 { "output", required_argument, NULL, 'o' },
580 { "noheadings",no_argument, NULL, 'n' },
581 { "reset", no_argument, NULL, 'r' },
582 { "raw", no_argument, NULL, OPT_RAW },
583 { "size", required_argument, NULL, 's' },
584 { "streams", required_argument, NULL, 't' },
585 { "version", no_argument, NULL, 'V' },
586 { NULL, 0, NULL, 0 }
587 };
588
589 static const ul_excl_t excl[] = {
590 { 'f', 'o', 'r' },
591 { 'o', 'r', 's' },
592 { 0 }
593 };
594 int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;
595
596 setlocale(LC_ALL, "");
597 bindtextdomain(PACKAGE, LOCALEDIR);
598 textdomain(PACKAGE);
599 atexit(close_stdout);
600
601 while ((c = getopt_long(argc, argv, "a:bfho:nrs:t:V", longopts, NULL)) != -1) {
602
603 err_exclusive_options(c, longopts, excl, excl_st);
604
605 switch (c) {
606 case 'a':
607 if (strcmp(optarg,"lzo") && strcmp(optarg,"lz4"))
608 errx(EXIT_FAILURE, _("unsupported algorithm: %s"),
609 optarg);
610 algorithm = optarg;
611 break;
612 case 'b':
613 inbytes = 1;
614 break;
615 case 'f':
616 find = 1;
617 break;
618 case 'o':
619 ncolumns = string_to_idarray(optarg,
620 columns, ARRAY_SIZE(columns),
621 column_name_to_id);
622 if (ncolumns < 0)
623 return EXIT_FAILURE;
624 break;
625 case 's':
626 size = strtosize_or_err(optarg, _("failed to parse size"));
627 act = A_CREATE;
628 break;
629 case 't':
630 nstreams = strtou64_or_err(optarg, _("failed to parse streams"));
631 break;
632 case 'r':
633 act = A_RESET;
634 break;
635 case OPT_RAW:
636 raw = 1;
637 break;
638 case 'n':
639 no_headings = 1;
640 break;
641 case 'V':
642 printf(UTIL_LINUX_VERSION);
643 return EXIT_SUCCESS;
644 case 'h':
86be6a32 645 usage();
0624d840 646 default:
677ec86c 647 errtryhelp(EXIT_FAILURE);
0624d840
KZ
648 }
649 }
650
651 if (find && optind < argc)
652 errx(EXIT_FAILURE, _("option --find is mutually exclusive "
1c35e625 653 "with <device>"));
0624d840
KZ
654 if (act == A_NONE)
655 act = find ? A_FINDONLY : A_STATUS;
656
657 if (act != A_RESET && optind + 1 < argc)
929c7b28 658 errx(EXIT_FAILURE, _("only one <device> at a time is allowed"));
0624d840 659
1fa6c3e0
SK
660 if ((act == A_STATUS || act == A_FINDONLY) && (algorithm || nstreams))
661 errx(EXIT_FAILURE, _("options --algorithm and --streams "
662 "must be combined with --size"));
663
0624d840
KZ
664 switch (act) {
665 case A_STATUS:
0624d840
KZ
666 if (!ncolumns) { /* default columns */
667 columns[ncolumns++] = COL_NAME;
668 columns[ncolumns++] = COL_ALGORITHM;
669 columns[ncolumns++] = COL_DISKSIZE;
670 columns[ncolumns++] = COL_ORIG_SIZE;
671 columns[ncolumns++] = COL_COMP_SIZE;
672 columns[ncolumns++] = COL_MEMTOTAL;
673 columns[ncolumns++] = COL_STREAMS;
674 columns[ncolumns++] = COL_MOUNTPOINT;
675 }
116c9ce2 676 if (optind < argc) {
0624d840 677 zram = new_zram(argv[optind++]);
116c9ce2 678 if (!zram_exist(zram))
0a55b319 679 err(EXIT_FAILURE, "%s", zram->devname);
116c9ce2 680 }
0624d840
KZ
681 status(zram);
682 free_zram(zram);
683 break;
684 case A_RESET:
685 if (optind == argc)
686 errx(EXIT_FAILURE, _("no device specified"));
687 while (optind < argc) {
688 zram = new_zram(argv[optind]);
116c9ce2
KZ
689 if (!zram_exist(zram)
690 || zram_set_u64parm(zram, "reset", 1)) {
0624d840
KZ
691 warn(_("%s: failed to reset"), zram->devname);
692 rc = 1;
693 }
62725810 694 zram_control_remove(zram);
0624d840
KZ
695 free_zram(zram);
696 optind++;
697 }
698 break;
699 case A_FINDONLY:
700 zram = find_free_zram();
701 if (!zram)
1c35e625 702 errx(EXIT_FAILURE, _("no free zram device found"));
0624d840
KZ
703 printf("%s\n", zram->devname);
704 free_zram(zram);
705 break;
706 case A_CREATE:
707 if (find) {
708 zram = find_free_zram();
709 if (!zram)
1c35e625 710 errx(EXIT_FAILURE, _("no free zram device found"));
0624d840
KZ
711 } else if (optind == argc)
712 errx(EXIT_FAILURE, _("no device specified"));
116c9ce2 713 else {
0624d840 714 zram = new_zram(argv[optind]);
116c9ce2 715 if (!zram_exist(zram))
0a55b319 716 err(EXIT_FAILURE, "%s", zram->devname);
116c9ce2 717 }
0624d840
KZ
718
719 if (zram_set_u64parm(zram, "reset", 1))
720 err(EXIT_FAILURE, _("%s: failed to reset"), zram->devname);
721
722 if (nstreams &&
723 zram_set_u64parm(zram, "max_comp_streams", nstreams))
724 err(EXIT_FAILURE, _("%s: failed to set number of streams"), zram->devname);
725
726 if (algorithm &&
727 zram_set_strparm(zram, "comp_algorithm", algorithm))
728 err(EXIT_FAILURE, _("%s: failed to set algorithm"), zram->devname);
729
730 if (zram_set_u64parm(zram, "disksize", size))
731 err(EXIT_FAILURE, _("%s: failed to set disksize (%ju bytes)"),
732 zram->devname, size);
733 if (find)
734 printf("%s\n", zram->devname);
735 free_zram(zram);
736 break;
737 }
738
739 return rc ? EXIT_FAILURE : EXIT_SUCCESS;
740}