72 static FILE *mnttab_file;
73 static char history_str[HIS_MAX_RECORD_LEN];
74 static boolean_t log_history = B_TRUE;
75
76 static int zfs_do_clone(int argc, char **argv);
77 static int zfs_do_create(int argc, char **argv);
78 static int zfs_do_destroy(int argc, char **argv);
79 static int zfs_do_get(int argc, char **argv);
80 static int zfs_do_inherit(int argc, char **argv);
81 static int zfs_do_list(int argc, char **argv);
82 static int zfs_do_mount(int argc, char **argv);
83 static int zfs_do_rename(int argc, char **argv);
84 static int zfs_do_rollback(int argc, char **argv);
85 static int zfs_do_set(int argc, char **argv);
86 static int zfs_do_upgrade(int argc, char **argv);
87 static int zfs_do_snapshot(int argc, char **argv);
88 static int zfs_do_unmount(int argc, char **argv);
89 static int zfs_do_share(int argc, char **argv);
90 static int zfs_do_unshare(int argc, char **argv);
91 static int zfs_do_send(int argc, char **argv);
92 static int zfs_do_receive(int argc, char **argv);
93 static int zfs_do_promote(int argc, char **argv);
94 static int zfs_do_userspace(int argc, char **argv);
95 static int zfs_do_allow(int argc, char **argv);
96 static int zfs_do_unallow(int argc, char **argv);
97 static int zfs_do_hold(int argc, char **argv);
98 static int zfs_do_holds(int argc, char **argv);
99 static int zfs_do_release(int argc, char **argv);
100 static int zfs_do_diff(int argc, char **argv);
101
102 /*
103 * Enable a reasonable set of defaults for libumem debugging on DEBUG builds.
104 */
105
106 #ifdef DEBUG
107 const char *
108 _umem_debug_init(void)
109 {
110 return ("default,verbose"); /* $UMEM_DEBUG setting */
111 }
114 _umem_logging_init(void)
115 {
116 return ("fail,contents"); /* $UMEM_LOGGING setting */
117 }
118 #endif
119
120 typedef enum {
121 HELP_CLONE,
122 HELP_CREATE,
123 HELP_DESTROY,
124 HELP_GET,
125 HELP_INHERIT,
126 HELP_UPGRADE,
127 HELP_LIST,
128 HELP_MOUNT,
129 HELP_PROMOTE,
130 HELP_RECEIVE,
131 HELP_RENAME,
132 HELP_ROLLBACK,
133 HELP_SEND,
134 HELP_SET,
135 HELP_SHARE,
136 HELP_SNAPSHOT,
137 HELP_UNMOUNT,
138 HELP_UNSHARE,
139 HELP_ALLOW,
140 HELP_UNALLOW,
141 HELP_USERSPACE,
142 HELP_GROUPSPACE,
143 HELP_HOLD,
144 HELP_HOLDS,
145 HELP_RELEASE,
146 HELP_DIFF,
147 } zfs_help_t;
148
149 typedef struct zfs_command {
150 const char *name;
151 int (*func)(int argc, char **argv);
152 zfs_help_t usage;
153 } zfs_command_t;
171 { "promote", zfs_do_promote, HELP_PROMOTE },
172 { "rename", zfs_do_rename, HELP_RENAME },
173 { NULL },
174 { "list", zfs_do_list, HELP_LIST },
175 { NULL },
176 { "set", zfs_do_set, HELP_SET },
177 { "get", zfs_do_get, HELP_GET },
178 { "inherit", zfs_do_inherit, HELP_INHERIT },
179 { "upgrade", zfs_do_upgrade, HELP_UPGRADE },
180 { "userspace", zfs_do_userspace, HELP_USERSPACE },
181 { "groupspace", zfs_do_userspace, HELP_GROUPSPACE },
182 { NULL },
183 { "mount", zfs_do_mount, HELP_MOUNT },
184 { "unmount", zfs_do_unmount, HELP_UNMOUNT },
185 { "share", zfs_do_share, HELP_SHARE },
186 { "unshare", zfs_do_unshare, HELP_UNSHARE },
187 { NULL },
188 { "send", zfs_do_send, HELP_SEND },
189 { "receive", zfs_do_receive, HELP_RECEIVE },
190 { NULL },
191 { "allow", zfs_do_allow, HELP_ALLOW },
192 { NULL },
193 { "unallow", zfs_do_unallow, HELP_UNALLOW },
194 { NULL },
195 { "hold", zfs_do_hold, HELP_HOLD },
196 { "holds", zfs_do_holds, HELP_HOLDS },
197 { "release", zfs_do_release, HELP_RELEASE },
198 { "diff", zfs_do_diff, HELP_DIFF },
199 };
200
201 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
202
203 zfs_command_t *current_command;
204
205 static const char *
206 get_usage(zfs_help_t idx)
207 {
208 switch (idx) {
209 case HELP_CLONE:
210 return (gettext("\tclone [-p] [-o property=value] ... "
237 "[filesystem|volume|snapshot] ...\n"));
238 case HELP_MOUNT:
239 return (gettext("\tmount\n"
240 "\tmount [-vO] [-o opts] <-a | filesystem>\n"));
241 case HELP_PROMOTE:
242 return (gettext("\tpromote <clone-filesystem>\n"));
243 case HELP_RECEIVE:
244 return (gettext("\treceive [-vnFu] <filesystem|volume|"
245 "snapshot>\n"
246 "\treceive [-vnFu] [-d | -e] <filesystem>\n"));
247 case HELP_RENAME:
248 return (gettext("\trename [-f] <filesystem|volume|snapshot> "
249 "<filesystem|volume|snapshot>\n"
250 "\trename [-f] -p <filesystem|volume> <filesystem|volume>\n"
251 "\trename -r <snapshot> <snapshot>"));
252 case HELP_ROLLBACK:
253 return (gettext("\trollback [-rRf] <snapshot>\n"));
254 case HELP_SEND:
255 return (gettext("\tsend [-DnPpRv] [-[iI] snapshot] "
256 "<snapshot>\n"));
257 case HELP_SET:
258 return (gettext("\tset <property=value> "
259 "<filesystem|volume|snapshot> ...\n"));
260 case HELP_SHARE:
261 return (gettext("\tshare <-a | filesystem>\n"));
262 case HELP_SNAPSHOT:
263 return (gettext("\tsnapshot [-r] [-o property=value] ... "
264 "<filesystem@snapname|volume@snapname> ...\n"));
265 case HELP_UNMOUNT:
266 return (gettext("\tunmount [-f] "
267 "<-a | filesystem|mountpoint>\n"));
268 case HELP_UNSHARE:
269 return (gettext("\tunshare "
270 "<-a | filesystem|mountpoint>\n"));
271 case HELP_ALLOW:
272 return (gettext("\tallow <filesystem|volume>\n"
273 "\tallow [-ldug] "
274 "<\"everyone\"|user|group>[,...] <perm|@setname>[,...]\n"
275 "\t <filesystem|volume>\n"
276 "\tallow [-ld] -e <perm|@setname>[,...] "
3708 }
3709 if (argc > 1) {
3710 (void) fprintf(stderr, gettext("too many arguments\n"));
3711 usage(B_FALSE);
3712 }
3713
3714 if (isatty(STDIN_FILENO)) {
3715 (void) fprintf(stderr,
3716 gettext("Error: Backup stream can not be read "
3717 "from a terminal.\n"
3718 "You must redirect standard input.\n"));
3719 return (1);
3720 }
3721
3722 err = zfs_receive(g_zfs, argv[0], &flags, STDIN_FILENO, NULL);
3723
3724 return (err != 0);
3725 }
3726
3727 /*
3728 * allow/unallow stuff
3729 */
3730 /* copied from zfs/sys/dsl_deleg.h */
3731 #define ZFS_DELEG_PERM_CREATE "create"
3732 #define ZFS_DELEG_PERM_DESTROY "destroy"
3733 #define ZFS_DELEG_PERM_SNAPSHOT "snapshot"
3734 #define ZFS_DELEG_PERM_ROLLBACK "rollback"
3735 #define ZFS_DELEG_PERM_CLONE "clone"
3736 #define ZFS_DELEG_PERM_PROMOTE "promote"
3737 #define ZFS_DELEG_PERM_RENAME "rename"
3738 #define ZFS_DELEG_PERM_MOUNT "mount"
3739 #define ZFS_DELEG_PERM_SHARE "share"
3740 #define ZFS_DELEG_PERM_SEND "send"
3741 #define ZFS_DELEG_PERM_RECEIVE "receive"
3742 #define ZFS_DELEG_PERM_ALLOW "allow"
3743 #define ZFS_DELEG_PERM_USERPROP "userprop"
3744 #define ZFS_DELEG_PERM_VSCAN "vscan" /* ??? */
3745 #define ZFS_DELEG_PERM_USERQUOTA "userquota"
3746 #define ZFS_DELEG_PERM_GROUPQUOTA "groupquota"
3747 #define ZFS_DELEG_PERM_USERUSED "userused"
|
72 static FILE *mnttab_file;
73 static char history_str[HIS_MAX_RECORD_LEN];
74 static boolean_t log_history = B_TRUE;
75
76 static int zfs_do_clone(int argc, char **argv);
77 static int zfs_do_create(int argc, char **argv);
78 static int zfs_do_destroy(int argc, char **argv);
79 static int zfs_do_get(int argc, char **argv);
80 static int zfs_do_inherit(int argc, char **argv);
81 static int zfs_do_list(int argc, char **argv);
82 static int zfs_do_mount(int argc, char **argv);
83 static int zfs_do_rename(int argc, char **argv);
84 static int zfs_do_rollback(int argc, char **argv);
85 static int zfs_do_set(int argc, char **argv);
86 static int zfs_do_upgrade(int argc, char **argv);
87 static int zfs_do_snapshot(int argc, char **argv);
88 static int zfs_do_unmount(int argc, char **argv);
89 static int zfs_do_share(int argc, char **argv);
90 static int zfs_do_unshare(int argc, char **argv);
91 static int zfs_do_send(int argc, char **argv);
92 static int zfs_do_fits_send(int argc, char **argv);
93 static int zfs_do_receive(int argc, char **argv);
94 static int zfs_do_promote(int argc, char **argv);
95 static int zfs_do_userspace(int argc, char **argv);
96 static int zfs_do_allow(int argc, char **argv);
97 static int zfs_do_unallow(int argc, char **argv);
98 static int zfs_do_hold(int argc, char **argv);
99 static int zfs_do_holds(int argc, char **argv);
100 static int zfs_do_release(int argc, char **argv);
101 static int zfs_do_diff(int argc, char **argv);
102
103 /*
104 * Enable a reasonable set of defaults for libumem debugging on DEBUG builds.
105 */
106
107 #ifdef DEBUG
108 const char *
109 _umem_debug_init(void)
110 {
111 return ("default,verbose"); /* $UMEM_DEBUG setting */
112 }
115 _umem_logging_init(void)
116 {
117 return ("fail,contents"); /* $UMEM_LOGGING setting */
118 }
119 #endif
120
121 typedef enum {
122 HELP_CLONE,
123 HELP_CREATE,
124 HELP_DESTROY,
125 HELP_GET,
126 HELP_INHERIT,
127 HELP_UPGRADE,
128 HELP_LIST,
129 HELP_MOUNT,
130 HELP_PROMOTE,
131 HELP_RECEIVE,
132 HELP_RENAME,
133 HELP_ROLLBACK,
134 HELP_SEND,
135 HELP_FITS_SEND,
136 HELP_SET,
137 HELP_SHARE,
138 HELP_SNAPSHOT,
139 HELP_UNMOUNT,
140 HELP_UNSHARE,
141 HELP_ALLOW,
142 HELP_UNALLOW,
143 HELP_USERSPACE,
144 HELP_GROUPSPACE,
145 HELP_HOLD,
146 HELP_HOLDS,
147 HELP_RELEASE,
148 HELP_DIFF,
149 } zfs_help_t;
150
151 typedef struct zfs_command {
152 const char *name;
153 int (*func)(int argc, char **argv);
154 zfs_help_t usage;
155 } zfs_command_t;
173 { "promote", zfs_do_promote, HELP_PROMOTE },
174 { "rename", zfs_do_rename, HELP_RENAME },
175 { NULL },
176 { "list", zfs_do_list, HELP_LIST },
177 { NULL },
178 { "set", zfs_do_set, HELP_SET },
179 { "get", zfs_do_get, HELP_GET },
180 { "inherit", zfs_do_inherit, HELP_INHERIT },
181 { "upgrade", zfs_do_upgrade, HELP_UPGRADE },
182 { "userspace", zfs_do_userspace, HELP_USERSPACE },
183 { "groupspace", zfs_do_userspace, HELP_GROUPSPACE },
184 { NULL },
185 { "mount", zfs_do_mount, HELP_MOUNT },
186 { "unmount", zfs_do_unmount, HELP_UNMOUNT },
187 { "share", zfs_do_share, HELP_SHARE },
188 { "unshare", zfs_do_unshare, HELP_UNSHARE },
189 { NULL },
190 { "send", zfs_do_send, HELP_SEND },
191 { "receive", zfs_do_receive, HELP_RECEIVE },
192 { NULL },
193 { "fits-send", zfs_do_fits_send, HELP_FITS_SEND },
194 { NULL },
195 { "allow", zfs_do_allow, HELP_ALLOW },
196 { NULL },
197 { "unallow", zfs_do_unallow, HELP_UNALLOW },
198 { NULL },
199 { "hold", zfs_do_hold, HELP_HOLD },
200 { "holds", zfs_do_holds, HELP_HOLDS },
201 { "release", zfs_do_release, HELP_RELEASE },
202 { "diff", zfs_do_diff, HELP_DIFF },
203 };
204
205 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
206
207 zfs_command_t *current_command;
208
209 static const char *
210 get_usage(zfs_help_t idx)
211 {
212 switch (idx) {
213 case HELP_CLONE:
214 return (gettext("\tclone [-p] [-o property=value] ... "
241 "[filesystem|volume|snapshot] ...\n"));
242 case HELP_MOUNT:
243 return (gettext("\tmount\n"
244 "\tmount [-vO] [-o opts] <-a | filesystem>\n"));
245 case HELP_PROMOTE:
246 return (gettext("\tpromote <clone-filesystem>\n"));
247 case HELP_RECEIVE:
248 return (gettext("\treceive [-vnFu] <filesystem|volume|"
249 "snapshot>\n"
250 "\treceive [-vnFu] [-d | -e] <filesystem>\n"));
251 case HELP_RENAME:
252 return (gettext("\trename [-f] <filesystem|volume|snapshot> "
253 "<filesystem|volume|snapshot>\n"
254 "\trename [-f] -p <filesystem|volume> <filesystem|volume>\n"
255 "\trename -r <snapshot> <snapshot>"));
256 case HELP_ROLLBACK:
257 return (gettext("\trollback [-rRf] <snapshot>\n"));
258 case HELP_SEND:
259 return (gettext("\tsend [-DnPpRv] [-[iI] snapshot] "
260 "<snapshot>\n"));
261 case HELP_FITS_SEND:
262 return (gettext("\tfits-send [-v] [-i snapshot] "
263 "<snapshot>\n"));
264 case HELP_SET:
265 return (gettext("\tset <property=value> "
266 "<filesystem|volume|snapshot> ...\n"));
267 case HELP_SHARE:
268 return (gettext("\tshare <-a | filesystem>\n"));
269 case HELP_SNAPSHOT:
270 return (gettext("\tsnapshot [-r] [-o property=value] ... "
271 "<filesystem@snapname|volume@snapname> ...\n"));
272 case HELP_UNMOUNT:
273 return (gettext("\tunmount [-f] "
274 "<-a | filesystem|mountpoint>\n"));
275 case HELP_UNSHARE:
276 return (gettext("\tunshare "
277 "<-a | filesystem|mountpoint>\n"));
278 case HELP_ALLOW:
279 return (gettext("\tallow <filesystem|volume>\n"
280 "\tallow [-ldug] "
281 "<\"everyone\"|user|group>[,...] <perm|@setname>[,...]\n"
282 "\t <filesystem|volume>\n"
283 "\tallow [-ld] -e <perm|@setname>[,...] "
3715 }
3716 if (argc > 1) {
3717 (void) fprintf(stderr, gettext("too many arguments\n"));
3718 usage(B_FALSE);
3719 }
3720
3721 if (isatty(STDIN_FILENO)) {
3722 (void) fprintf(stderr,
3723 gettext("Error: Backup stream can not be read "
3724 "from a terminal.\n"
3725 "You must redirect standard input.\n"));
3726 return (1);
3727 }
3728
3729 err = zfs_receive(g_zfs, argv[0], &flags, STDIN_FILENO, NULL);
3730
3731 return (err != 0);
3732 }
3733
3734 /*
3735 * Send a backup stream to stdout in fits format.
3736 */
3737 static int
3738 zfs_do_fits_send(int argc, char **argv)
3739 {
3740 char *fromname = NULL;
3741 char *toname = NULL;
3742 char *cp;
3743 zfs_handle_t *zhp;
3744 sendflags_t flags = { 0 };
3745 int c, err;
3746
3747 /* check options */
3748 while ((c = getopt(argc, argv, ":i:v")) != -1) {
3749 switch (c) {
3750 case 'i':
3751 if (fromname)
3752 usage(B_FALSE);
3753 fromname = optarg;
3754 break;
3755 case 'v':
3756 flags.verbose = B_TRUE;
3757 break;
3758 case ':':
3759 (void) fprintf(stderr, gettext("missing argument for "
3760 "'%c' option\n"), optopt);
3761 usage(B_FALSE);
3762 break;
3763 case '?':
3764 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3765 optopt);
3766 usage(B_FALSE);
3767 }
3768 }
3769
3770 argc -= optind;
3771 argv += optind;
3772
3773 /* check number of arguments */
3774 if (argc < 1) {
3775 (void) fprintf(stderr, gettext("missing snapshot argument\n"));
3776 usage(B_FALSE);
3777 }
3778 if (argc > 1) {
3779 (void) fprintf(stderr, gettext("too many arguments\n"));
3780 usage(B_FALSE);
3781 }
3782
3783 if (isatty(STDOUT_FILENO)) {
3784 (void) fprintf(stderr,
3785 gettext("Error: Stream can not be written to a terminal.\n"
3786 "You must redirect standard output.\n"));
3787 return (1);
3788 }
3789
3790 cp = strchr(argv[0], '@');
3791 if (cp == NULL) {
3792 (void) fprintf(stderr,
3793 gettext("argument must be a snapshot\n"));
3794 usage(B_FALSE);
3795 }
3796 *cp = '\0';
3797 toname = cp + 1;
3798 zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_FILESYSTEM);
3799 if (zhp == NULL)
3800 return (1);
3801
3802 /*
3803 * If they specified the full path to the snapshot, chop off
3804 * everything except the short name of the snapshot, but special
3805 * case if they specify the origin.
3806 */
3807 if (fromname && (cp = strchr(fromname, '@')) != NULL) {
3808 char origin[ZFS_MAXNAMELEN];
3809 zprop_source_t src;
3810
3811 (void) zfs_prop_get(zhp, ZFS_PROP_ORIGIN,
3812 origin, sizeof (origin), &src, NULL, 0, B_FALSE);
3813
3814 if (strcmp(origin, fromname) == 0) {
3815 fromname = NULL;
3816 flags.fromorigin = B_TRUE;
3817 } else {
3818 *cp = '\0';
3819 if (cp != fromname && strcmp(argv[0], fromname)) {
3820 (void) fprintf(stderr,
3821 gettext("incremental source must be "
3822 "in same filesystem\n"));
3823 usage(B_FALSE);
3824 }
3825 fromname = cp + 1;
3826 if (strchr(fromname, '@') || strchr(fromname, '/')) {
3827 (void) fprintf(stderr,
3828 gettext("invalid incremental source\n"));
3829 usage(B_FALSE);
3830 }
3831 }
3832 }
3833
3834 err = zfs_fits_send(zhp, fromname, toname, &flags, STDOUT_FILENO,
3835 NULL, 0);
3836
3837 zfs_close(zhp);
3838
3839 return (err != 0);
3840 }
3841
3842 /*
3843 * allow/unallow stuff
3844 */
3845 /* copied from zfs/sys/dsl_deleg.h */
3846 #define ZFS_DELEG_PERM_CREATE "create"
3847 #define ZFS_DELEG_PERM_DESTROY "destroy"
3848 #define ZFS_DELEG_PERM_SNAPSHOT "snapshot"
3849 #define ZFS_DELEG_PERM_ROLLBACK "rollback"
3850 #define ZFS_DELEG_PERM_CLONE "clone"
3851 #define ZFS_DELEG_PERM_PROMOTE "promote"
3852 #define ZFS_DELEG_PERM_RENAME "rename"
3853 #define ZFS_DELEG_PERM_MOUNT "mount"
3854 #define ZFS_DELEG_PERM_SHARE "share"
3855 #define ZFS_DELEG_PERM_SEND "send"
3856 #define ZFS_DELEG_PERM_RECEIVE "receive"
3857 #define ZFS_DELEG_PERM_ALLOW "allow"
3858 #define ZFS_DELEG_PERM_USERPROP "userprop"
3859 #define ZFS_DELEG_PERM_VSCAN "vscan" /* ??? */
3860 #define ZFS_DELEG_PERM_USERQUOTA "userquota"
3861 #define ZFS_DELEG_PERM_GROUPQUOTA "groupquota"
3862 #define ZFS_DELEG_PERM_USERUSED "userused"
|