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