summaryrefslogtreecommitdiff
path: root/libfdisk/src/context.c
diff options
context:
space:
mode:
Diffstat (limited to 'libfdisk/src/context.c')
-rw-r--r--libfdisk/src/context.c152
1 files changed, 128 insertions, 24 deletions
diff --git a/libfdisk/src/context.c b/libfdisk/src/context.c
index 7569e5b52..0de2d2a59 100644
--- a/libfdisk/src/context.c
+++ b/libfdisk/src/context.c
@@ -21,7 +21,6 @@ struct fdisk_context *fdisk_new_context(void)
cxt->labels[ cxt->nlabels++ ] = fdisk_new_gpt_label(cxt);
cxt->labels[ cxt->nlabels++ ] = fdisk_new_dos_label(cxt);
cxt->labels[ cxt->nlabels++ ] = fdisk_new_bsd_label(cxt);
- cxt->labels[ cxt->nlabels++ ] = fdisk_new_mac_label(cxt);
cxt->labels[ cxt->nlabels++ ] = fdisk_new_sgi_label(cxt);
cxt->labels[ cxt->nlabels++ ] = fdisk_new_sun_label(cxt);
@@ -33,9 +32,9 @@ struct fdisk_context *fdisk_new_nested_context(struct fdisk_context *parent,
const char *name)
{
struct fdisk_context *cxt;
+ struct fdisk_label *lb = NULL;
assert(parent);
- assert(name);
cxt = calloc(1, sizeof(*cxt));
if (!cxt)
@@ -55,10 +54,28 @@ struct fdisk_context *fdisk_new_nested_context(struct fdisk_context *parent,
cxt->first_lba = parent->first_lba;
cxt->total_sectors = parent->total_sectors;
+ cxt->ask_cb = parent->ask_cb;
+ cxt->ask_data = parent->ask_data;
+
cxt->geom = parent->geom;
- if (strcmp(name, "bsd") == 0)
- cxt->label = cxt->labels[ cxt->nlabels++ ] = fdisk_new_bsd_label(cxt);
+ if (name && strcmp(name, "bsd") == 0)
+ lb = cxt->labels[ cxt->nlabels++ ] = fdisk_new_bsd_label(cxt);
+
+ if (lb) {
+ DBG(LABEL, dbgprint("probing for nested %s", lb->name));
+
+ cxt->label = lb;
+
+ if (lb->op->probe(cxt) == 1)
+ __fdisk_context_switch_label(cxt, lb);
+ else {
+ DBG(LABEL, dbgprint("not found %s label", lb->name));
+ if (lb->op->deinit)
+ lb->op->deinit(lb);
+ cxt->label = NULL;
+ }
+ }
return cxt;
}
@@ -77,18 +94,46 @@ struct fdisk_label *fdisk_context_get_label(struct fdisk_context *cxt, const cha
return cxt->label;
for (i = 0; i < cxt->nlabels; i++)
- if (strcmp(cxt->labels[i]->name, name) == 0)
+ if (cxt->labels[i]
+ && strcmp(cxt->labels[i]->name, name) == 0)
return cxt->labels[i];
DBG(LABEL, dbgprint("failed to found %s label driver\n", name));
return NULL;
}
+int fdisk_context_next_label(struct fdisk_context *cxt, struct fdisk_label **lb)
+{
+ size_t i;
+ struct fdisk_label *res = NULL;
+
+ if (!lb || !cxt)
+ return -EINVAL;
+
+ if (!*lb)
+ res = cxt->labels[0];
+ else {
+ for (i = 1; i < cxt->nlabels; i++) {
+ if (*lb == cxt->labels[i - 1]) {
+ res = cxt->labels[i];
+ break;
+ }
+ }
+ }
+
+ *lb = res;
+ return res ? 0 : 1;
+}
+
int __fdisk_context_switch_label(struct fdisk_context *cxt,
struct fdisk_label *lb)
{
- if (!lb)
+ if (!lb || !cxt)
return -EINVAL;
+ if (lb->disabled) {
+ DBG(LABEL, dbgprint("*** attempt to switch to disabled label %s -- ignore!", lb->name));
+ return -EINVAL;
+ }
cxt->label = lb;
DBG(LABEL, dbgprint("--> switching context to %s!", lb->name));
return 0;
@@ -105,7 +150,7 @@ static void reset_context(struct fdisk_context *cxt)
{
size_t i;
- DBG(CONTEXT, dbgprint("\n-----\nresetting context %p", cxt));
+ DBG(CONTEXT, dbgprint("*** resetting context %p", cxt));
/* reset drives' private data */
for (i = 0; i < cxt->nlabels; i++)
@@ -122,17 +167,7 @@ static void reset_context(struct fdisk_context *cxt)
cxt->dev_path = NULL;
cxt->firstsector = NULL;
- cxt->io_size = 0;
- cxt->optimal_io_size = 0;
- cxt->min_io_size = 0;
- cxt->phy_sector_size = 0;
- cxt->sector_size = 0;
- cxt->alignment_offset = 0;
- cxt->grain = 0;
- cxt->first_lba = 0;
- cxt->total_sectors = 0;
-
- memset(&cxt->geom, 0, sizeof(struct fdisk_geometry));
+ fdisk_zeroize_device_properties(cxt);
cxt->label = NULL;
}
@@ -158,12 +193,11 @@ int fdisk_context_assign_device(struct fdisk_context *cxt,
reset_context(cxt);
- if (readonly == 1 || (fd = open(fname, O_RDWR|O_CLOEXEC)) < 0) {
- if ((fd = open(fname, O_RDONLY|O_CLOEXEC)) < 0)
- return -errno;
- readonly = 1;
- }
+ fd = open(fname, (readonly ? O_RDONLY : O_RDWR ) | O_CLOEXEC);
+ if (fd < 0)
+ return -errno;
+ cxt->readonly = readonly;
cxt->dev_fd = fd;
cxt->dev_path = strdup(fname);
if (!cxt->dev_path)
@@ -178,7 +212,10 @@ int fdisk_context_assign_device(struct fdisk_context *cxt,
/* detect labels and apply labes specific stuff (e.g geomery)
* to the context */
fdisk_probe_labels(cxt);
- fdisk_reset_alignment(cxt);
+
+ /* let's apply user geometry *after* label prober
+ * to make it possible to override in-label setting */
+ fdisk_apply_user_device_properties(cxt);
DBG(CONTEXT, dbgprint("context %p initialized for %s [%s]",
cxt, fname,
@@ -189,6 +226,29 @@ fail:
return -errno;
}
+int fdisk_context_deassign_device(struct fdisk_context *cxt)
+{
+ assert(cxt);
+ assert(cxt->dev_fd >= 0);
+
+ if (fsync(cxt->dev_fd) || close(cxt->dev_fd)) {
+ fdisk_warn(cxt, _("%s: close device failed"), cxt->dev_path);
+ return -errno;
+ }
+
+ fdisk_info(cxt, _("Syncing disks."));
+ sync();
+
+ cxt->dev_fd = -1;
+ return 0;
+}
+
+int fdisk_context_is_readonly(struct fdisk_context *cxt)
+{
+ assert(cxt);
+ return cxt->readonly;
+}
+
/**
* fdisk_free_context:
* @cxt: fdisk context
@@ -237,6 +297,50 @@ int fdisk_context_set_ask(struct fdisk_context *cxt,
return 0;
}
+/**
+ * fdisk_context_enable_details:
+ * cxt: context
+ * enable: true/flase
+ *
+ * Enables or disables "details" display mode.
+ *
+ * Returns: 0 on success, < 0 on error.
+ */
+int fdisk_context_enable_details(struct fdisk_context *cxt, int enable)
+{
+ assert(cxt);
+ cxt->display_details = enable ? 1 : 0;
+ return 0;
+}
+
+int fdisk_context_display_details(struct fdisk_context *cxt)
+{
+ assert(cxt);
+ return cxt->display_details == 1;
+}
+
+/**
+ * fdisk_context_enable_listonly:
+ * cxt: context
+ * enable: true/flase
+ *
+ * Just list partition only, don't care about another details, mistakes, ...
+ *
+ * Returns: 0 on success, < 0 on error.
+ */
+int fdisk_context_enable_listonly(struct fdisk_context *cxt, int enable)
+{
+ assert(cxt);
+ cxt->listonly = enable ? 1 : 0;
+ return 0;
+}
+
+int fdisk_context_listonly(struct fdisk_context *cxt)
+{
+ assert(cxt);
+ return cxt->listonly == 1;
+}
+
/*
* @str: "cylinder" or "sector".