Changeset View
Changeset View
Standalone View
Standalone View
sys/boot/zfs/zfs.c
Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
#include <string.h> | #include <string.h> | ||||
#include <stand.h> | #include <stand.h> | ||||
#include <bootstrap.h> | #include <bootstrap.h> | ||||
#include "libzfs.h" | #include "libzfs.h" | ||||
#include "zfsimpl.c" | #include "zfsimpl.c" | ||||
/* Define the range of indexes to be populated with ZFS Boot Environments */ | |||||
#define ZFS_BE_FIRST 3 | |||||
#define ZFS_BE_LAST 8 | |||||
static int zfs_open(const char *path, struct open_file *f); | static int zfs_open(const char *path, struct open_file *f); | ||||
static int zfs_write(struct open_file *f, void *buf, size_t size, size_t *resid); | static int zfs_write(struct open_file *f, void *buf, size_t size, size_t *resid); | ||||
static int zfs_close(struct open_file *f); | static int zfs_close(struct open_file *f); | ||||
static int zfs_read(struct open_file *f, void *buf, size_t size, size_t *resid); | static int zfs_read(struct open_file *f, void *buf, size_t size, size_t *resid); | ||||
static off_t zfs_seek(struct open_file *f, off_t offset, int where); | static off_t zfs_seek(struct open_file *f, off_t offset, int where); | ||||
static int zfs_stat(struct open_file *f, struct stat *sb); | static int zfs_stat(struct open_file *f, struct stat *sb); | ||||
static int zfs_readdir(struct open_file *f, struct dirent *d); | static int zfs_readdir(struct open_file *f, struct dirent *d); | ||||
Show All 16 Lines | |||||
struct file { | struct file { | ||||
off_t f_seekp; /* seek pointer */ | off_t f_seekp; /* seek pointer */ | ||||
dnode_phys_t f_dnode; | dnode_phys_t f_dnode; | ||||
uint64_t f_zap_type; /* zap type for readdir */ | uint64_t f_zap_type; /* zap type for readdir */ | ||||
uint64_t f_num_leafs; /* number of fzap leaf blocks */ | uint64_t f_num_leafs; /* number of fzap leaf blocks */ | ||||
zap_leaf_phys_t *f_zap_leaf; /* zap leaf buffer */ | zap_leaf_phys_t *f_zap_leaf; /* zap leaf buffer */ | ||||
}; | }; | ||||
static int zfs_env_index; | |||||
/* | /* | ||||
* Open a file. | * Open a file. | ||||
*/ | */ | ||||
static int | static int | ||||
zfs_open(const char *upath, struct open_file *f) | zfs_open(const char *upath, struct open_file *f) | ||||
{ | { | ||||
struct zfsmount *mount = (struct zfsmount *)f->f_devdata; | struct zfsmount *mount = (struct zfsmount *)f->f_devdata; | ||||
struct file *fp; | struct file *fp; | ||||
▲ Show 20 Lines • Show All 595 Lines • ▼ Show 20 Lines | zfs_list(const char *name) | ||||
poolname[len] = '\0'; | poolname[len] = '\0'; | ||||
spa = spa_find_by_name(poolname); | spa = spa_find_by_name(poolname); | ||||
if (!spa) | if (!spa) | ||||
return (ENXIO); | return (ENXIO); | ||||
rv = zfs_lookup_dataset(spa, dsname, &objid); | rv = zfs_lookup_dataset(spa, dsname, &objid); | ||||
if (rv != 0) | if (rv != 0) | ||||
return (rv); | return (rv); | ||||
rv = zfs_list_dataset(spa, objid); | rv = zfs_list_dataset(spa, objid); | ||||
return (rv); | |||||
} | |||||
int | |||||
zfs_bootenv(const char *name) | |||||
{ | |||||
static char poolname[ZFS_MAXNAMELEN]; | |||||
uint64_t objid; | |||||
spa_t *spa; | |||||
const char *dsname; | |||||
int len; | |||||
int rv; | |||||
setenv("zfs_beroot", name, 1); | |||||
smh: check the return codes? more below too. | |||||
zfs_env_index = ZFS_BE_FIRST; | |||||
len = strlen(name); | |||||
dsname = strchr(name, '/'); | |||||
if (dsname != NULL) { | |||||
len = dsname - name; | |||||
dsname++; | |||||
} else | |||||
dsname = ""; | |||||
memcpy(poolname, name, len); | |||||
poolname[len] = '\0'; | |||||
spa = spa_find_by_name(poolname); | |||||
if (!spa) | |||||
return (ENXIO); | |||||
rv = zfs_lookup_dataset(spa, dsname, &objid); | |||||
if (rv != 0) | |||||
return (rv); | |||||
rv = zfs_callback_dataset(spa, objid, zfs_set_env); | |||||
Done Inline ActionsAvoid assignment and just: return (zfs_list_dataset(spa, objid)); smh: Avoid assignment and just:
return (zfs_list_dataset(spa, objid)); | |||||
return (rv); | |||||
} | |||||
int | |||||
zfs_set_env(const char *name) | |||||
{ | |||||
char *envname = NULL, *envval = NULL, *beroot; | |||||
int rv, i; | |||||
beroot = getenv("zfs_beroot"); | |||||
if (beroot == NULL) | |||||
return (1); | |||||
envname = malloc(32); | |||||
Done Inline Actionsstyle(9) braces around return. smh: style(9) braces around return. | |||||
envval = malloc(256); | |||||
baptUnsubmitted Done Inline ActionsInstead of unchecked malloc you could use static buffers? then in the next snprintf instead of hardcoding the size you could sizeof(envname) And the free in the end becomes useless bapt: Instead of unchecked malloc you could use static buffers?
char envname[32] ?
then in the next… | |||||
/* Don't overflow the menu, shuffle entries down to show the newest */ | |||||
if (zfs_env_index > ZFS_BE_LAST) { | |||||
for (i = ZFS_BE_FIRST; i < ZFS_BE_LAST; i++) { | |||||
snprintf(envname, 32, "bootenvmenu_caption[%d]", i); | |||||
snprintf(envval, 32, "bootenvmenu_caption[%d]", i + 1); | |||||
setenv(envname, getenv(envval), 1); | |||||
snprintf(envname, 32, "bootenvansi_caption[%d]", i); | |||||
snprintf(envval, 32, "bootenvansi_caption[%d]", i + 1); | |||||
setenv(envname, getenv(envval), 1); | |||||
snprintf(envname, 32, "bootenv_root[%d]", i); | |||||
snprintf(envval, 32, "bootenv_root[%d]", i + 1); | |||||
setenv(envname, getenv(envval), 1); | |||||
} | |||||
zfs_env_index = ZFS_BE_LAST; | |||||
} | |||||
Done Inline Actionsmove up to return early. smh: move up to return early. | |||||
snprintf(envname, 32, "bootenvmenu_caption[%d]", zfs_env_index); | |||||
snprintf(envval, 256, "%s", name); | |||||
rv = setenv(envname, envval, 1); | |||||
snprintf(envname, 32, "bootenvansi_caption[%d]", zfs_env_index); | |||||
rv = setenv(envname, envval, 1); | |||||
snprintf(envname, 32, "bootenvmenu_command[%d]", zfs_env_index); | |||||
rv = setenv(envname, "set_bootenv", 1); | |||||
snprintf(envname, 32, "bootenv_root[%d]", zfs_env_index); | |||||
snprintf(envval, 256, "zfs:%s/%s", beroot, name); | |||||
rv = setenv(envname, envval, 1); | |||||
if (zfs_env_index <= ZFS_BE_LAST) | |||||
zfs_env_index++; | |||||
Done Inline Actionsstyle(9) more below too. if (rv != 0) return (rv); smh: style(9) more below too.
if (rv != 0)
return (rv); | |||||
free(envname); | |||||
Done Inline ActionsCould the early returns here leave it in an inconsistent state that may course an issue? smh: Could the early returns here leave it in an inconsistent state that may course an issue? | |||||
Done Inline ActionsPossibly, switching them to break allanjude: Possibly, switching them to break | |||||
free(envval); | |||||
return (rv); | return (rv); | ||||
Done Inline Actionsuse sizeof(envname), more below. smh: use sizeof(envname), more below. | |||||
} | } | ||||
No newline at end of file | |||||
Done Inline ActionsAs zfs_env_index is always incremented could be extracted above so we have the following instead? zfs_env_index++; if (zfs_env_index > ZFS_BE_LAST) break; smh: As zfs_env_index is always incremented could be extracted above so we have the following… | |||||
Done Inline Actionsuse sizeof(enval) smh: use sizeof(enval) | |||||
Done Inline Actionsrv here is likely to be useless due to use by loop above, should that use a seperate var or just (void)unsetenv(envname) ? smh: rv here is likely to be useless due to use by loop above, should that use a seperate var or… | |||||
Done Inline Actionsuse sizeof(envname) more below smh: use sizeof(envname) more below |
check the return codes? more below too.